Subversion Repositories tendra.SVN

Rev

Rev 124 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6 7u83 1
#!/usr/bin/env perl
2
 
3
###############################################################################
125 7u83 4
$[    = 0 ;
6 7u83 5
$prog = $0;
125 7u83 6
($tmp = rindex ($prog, "/")) && ($prog = substr ($prog, $tmp + 0 ));
6 7u83 7
###############################################################################
8
 
9
sub fatal {
10
    print STDERR ($prog, ": fatal: ", @_, "\n");
11
    exit (1);
12
}
13
 
14
sub ifatal {
15
    print STDERR ($prog, ": fatal: ", $lexer'file, ": ", $lexer'line_num, ": ",
16
		  @_, "\n");
17
    exit (1);
18
}
19
 
20
###############################################################################
21
### Lexical analyser:
22
 
23
$lexer'file		= undef;
24
$lexer'line_num		= undef;
25
$lexer'line		= undef;
26
 
27
###############################################################################
28
 
29
$TOK_EOF		= 0;
30
$TOK_OPEN_BRACE		= 1;
31
$TOK_CLOSE_BRACE	= 2;
32
$TOK_COMMA		= 3;
33
$TOK_SEMI_COLON		= 4;
34
$TOK_COLON		= 5;
35
$TOK_STRING		= 6;
36
$TOK_PROGRAM		= 7;
37
$TOK_SEVERITY		= 8;
38
$TOK_HEADER		= 9;
39
$TOK_C_HEADER		= 10;
40
$TOK_OPEN		= 11;
41
$TOK_CLOSE		= 12;
42
 
43
%error_severity		= (
44
	"info",		"ERROR_SEVERITY_INFORMATION",
45
	"information",	"ERROR_SEVERITY_INFORMATION",
46
	"warning",	"ERROR_SEVERITY_WARNING",
47
	"error",	"ERROR_SEVERITY_ERROR",
48
	"fatal",	"ERROR_SEVERITY_FATAL",
49
	"internal",	"ERROR_SEVERITY_INTERNAL",
50
);
51
 
52
###############################################################################
53
 
54
sub reset_lexer {
55
    local ($file) = @_;
56
 
57
    $lexer'file     = $file;
58
    $lexer'line_num = 0;
59
    $lexer'line     = "";
60
    open (INFILE, "<" . $file) ||
61
	&fatal ("cannot open input file '", $file, "'");
62
}
63
 
64
sub lexer'read_string {
65
    local ($string) = "";
66
 
67
    read_string: {
68
	(($lexer'line eq "") &&
69
	    (($lexer'line = <INFILE>), ($lexer'line_num ++)));
70
	(defined ($lexer'line)) ||
71
	    &ifatal ("unexpected end of file in string");
72
 
73
	if ($lexer'line =~ s/^([^"]*)"//) {
74
	    $string .= $1;
75
	} else {
76
	    $string    .= $lexer'line;
77
	    $lexer'line = "";
78
	    redo read_string;
79
	}
80
    }
81
    $string;
82
}
83
 
84
sub lexer'read_program {
85
    local ($program) = "";
86
    local ($index, $tmp);
87
 
88
    read_program: {
89
	(($lexer'line eq "") &&
90
	    (($lexer'line = <INFILE>), ($lexer'line_num ++)));
91
	(defined ($lexer'line)) ||
92
	    &ifatal ("unexpected end of file in program segment");
93
 
94
	if ($index = index ($lexer'line, "]\$")) {
125 7u83 95
	    $tmp        = substr ($lexer'line, 0, $index - 1);
96
	    $lexer'line = substr ($lexer'line, $index + 1);
6 7u83 97
	    $tmp        =~ s/^[ \t]*//;
98
	    $program   .= $tmp;
99
	} else {
100
	    $program   .= $lexer'line;
101
	    $lexer'line = "";
102
	    redo read_program;
103
	}
104
    }
105
    $program;
106
}
107
 
108
sub next_token {
109
    local ($token, $data);
110
 
111
    get_token: {
112
	(($lexer'line eq "") &&
113
	    (($lexer'line = <INFILE>), ($lexer'line_num ++)));
125 7u83 114
 
115
    printf( "IIIIIIIIIIIIII %s - %d\n", $lexer'line,$lexer'line_num );
116
 
6 7u83 117
	(defined ($lexer'line)) || return ($TOK_EOF, 0);
118
	$lexer'line =~ s/^[ \t\n]*(#.*$)?\n?//;
119
	($lexer'line eq "") && redo get_token;
125 7u83 120
    printf( "XIIIIIIIIIIIIII %s - %d\n", $lexer'line,$lexer'line_num );
6 7u83 121
 
122
	if ($lexer'line =~ s/^{//) {
123
	    $token = $TOK_OPEN_BRACE;
124
	    $data  = 0;
125
	} elsif ($lexer'line =~ s/^}//) {
126
	    $token = $TOK_CLOSE_BRACE;
127
	    $data  = 0;
128
	} elsif ($lexer'line =~ s/^\(//) {
129
	    $token = $TOK_OPEN;
130
	    $data  = 0;
131
	} elsif ($lexer'line =~ s/^\)//) {
132
	    $token = $TOK_CLOSE;
133
	    $data  = 0;
134
	} elsif ($lexer'line =~ s/^,//) {
135
	    $token = $TOK_COMMA;
136
	    $data  = 0;
137
	} elsif ($lexer'line =~ s/^;//) {
138
	    $token = $TOK_SEMI_COLON;
139
	    $data  = 0;
140
	} elsif ($lexer'line =~ s/^://) {
141
	    $token = $TOK_COLON;
142
	    $data  = 0;
143
	} elsif ($lexer'line =~ s/^"//) {
144
	    $token = $TOK_STRING;
145
	    $data  = &lexer'read_string;
146
	} elsif ($lexer'line =~ s/^\$\[([ \t]*\n)?//) {
147
	    $token = $TOK_PROGRAM;
148
	    $data  = &lexer'read_program;
149
	} elsif ($lexer'line =~ s/^header\(c\)//) {
150
	    $token = $TOK_C_HEADER;
151
	    $data  = 0;
152
	} elsif ($lexer'line =~ s/^header\(h\)//) {
153
	    $token = $TOK_HEADER;
154
	    $data  = 0;
155
	} elsif ($lexer'line =~ s/^header//) {
156
	    $token = $TOK_HEADER;
157
	    $data  = 0;
158
	} elsif ($lexer'line =~ s/^[A-Za-z_]+//) {
159
	    $token = $TOK_SEVERITY;
160
	    $data  = $error_severity{$&};
161
	    defined ($data) ||
162
		&ifatal ("unknown error severity '", $&, "'");
163
	} elsif ($lexer'line =~ s/^.//) {
164
	    &ifatal ("illegal character '", $&, "'");
165
	}
166
    }
167
    ($token, $data);
168
}
169
 
170
###############################################################################
171
### Parser:
172
 
173
$error_header		= "";
174
$error_c_header		= "";
175
$error_tag_index	= 0;
176
$error_struct_num	= 0;
177
$error_tproc_num	= 0;
178
 
179
@error_tag_order	= ();
180
@error_order		= ();
181
@error_structures	= ();
182
@error_tag_procs	= ();
183
 
184
%error_tags		= ();
185
%error_tag_index	= ();
186
%error_severities	= ();
187
%error_munged_names	= ();
188
%error_messages		= ();
189
%error_client_data	= ();
190
%error_struct_match	= ();
191
%error_struct_name	= ();
192
%error_proc_decs	= ();
193
%error_proc_defs	= ();
194
%error_index		= ();
195
%error_tproc_match	= ();
196
%error_tproc_name	= ();
197
 
198
###############################################################################
199
 
200
sub munge_name {
201
    local ($name) = @_;
202
 
203
    $name =~ s/[^A-Za-z0-9_]/_/g;
204
    $name;
205
}
206
 
207
sub basename {
208
    local ($name) = @_;
209
    local ($tmp);
210
 
125 7u83 211
    ($tmp = rindex ($name, "/")) && ($name = substr ($name, $tmp + 0));
6 7u83 212
    $name;
213
}
214
 
215
sub find_tags {
216
    local ($mesg) = @_;
217
    local (%tag_names);
218
 
219
    while ($mesg =~ /\$\{([^\}\n]+)\}/) {
220
	$tag_names{$1} = 1;
221
	$mesg          = $';
222
    }
223
    keys (%tag_names);
224
}
225
 
226
sub indent_to {
227
    local ($prefix, $col) = @_;
228
    local ($length);
229
 
230
    if (($length = length ($prefix)) >= $col) {
231
	" ";
232
    } else {
233
	(" " x ($col - $length));
234
    }
235
}
236
 
237
###############################################################################
238
 
239
sub parse_param_list {
240
    local ($error, *param_types, *param_order) = @_;
241
    local ($token, $data, $name, $type);
242
 
243
    parse_param: {
244
	if ((($token, $data) = &next_token), ($token != $TOK_STRING)) {
245
	    &ifatal ("expected parameter name string");
246
	}
247
	$name = $data;
248
	if ((($token, $data) = &next_token), ($token != $TOK_COLON)) {
249
	    &ifatal ("expected ':'");
250
	}
251
	if ((($token, $data) = &next_token), ($token != $TOK_STRING)) {
252
	    &ifatal ("expected parameter type string");
253
	}
254
	$type = $data;
255
	if (defined ($param_types{$name})) {
256
	    &fatal ("parameter '", $name, "' already defined in error '",
257
		    $error, "'");
258
	} else {
259
	    $param_types{$name} = $type;
260
	    push (@param_order, $name);
261
	}
262
	if ((($token, $data) = &next_token), ($token == $TOK_COMMA)) {
263
	    redo parse_param;
264
	} elsif ($token != $TOK_CLOSE) {
265
	    &ifatal ("expected ')'");
266
	}
267
    }
268
}
269
 
270
sub parse_error_header {
271
    local ($severity, *tag_names, *param_types, *param_order) = @_;
272
    local ($token, $data, $name, $munged_name, $tmp);
273
 
274
    if ((($token, $data) = &next_token), ($token != $TOK_STRING)) {
275
	&ifatal ("expected error name string");
276
    }
277
    $name = $data;
278
    if (defined ($error_severities{$name})) {
279
	&ifatal ("error '", $name, "' is already defined");
280
    }
281
    $error_severities{$name} = $severity;
282
    if ((($token, $data) = &next_token), ($token == $TOK_COLON)) {
283
	if ((($token, $data) = &next_token), ($token != $TOK_STRING)) {
284
	    &ifatal ("expected error function name string");
285
	} elsif (($data =~ /[^A-Za-z_0-9]/) || ($data =~ /^[0-9]/)) {
286
	    &ifatal ("illegal error function name string '", $data, "'");
287
	}
288
	$munged_name = $data;
289
	($token, $data) = &next_token;
290
    } else {
291
	$munged_name = &munge_name ($name);
292
    }
293
    if (defined ($tmp = $error_munged_names{$munged_name})) {
294
	&ifatal ("error '", $name, "' clashes with error '", $tmp, "'");
295
    }
296
    $error_munged_names{$munged_name} = $name;
297
    if ($token == $TOK_OPEN) {
298
	&parse_param_list ($error, *param_types, *param_order);
299
	($token, $data) = &next_token;
300
    }
301
    if ($token != $TOK_OPEN_BRACE) {
302
	&ifatal ("expected '{'");
303
    }
304
    if ((($token, $data) = &next_token), ($token != $TOK_STRING)) {
305
	&ifatal ("expected error message text string");
306
    }
307
    $error_messages{$name} = $data;
308
    @tag_names = &find_tags ($data);
309
    ($name, $munged_name);
310
}
311
 
312
sub parse_error_tag {
313
    local ($name, *tag_types, *tag_names, *tag_mnames, *tag_code, *tag_init,
314
	   *tag_order, *param_types) = @_;
315
    local ($token, $data, $tag_name, $tag_type, $tag_code, $tag_init);
316
    local ($munged_name, $tmp);
317
 
318
    if ((($token, $data) = &next_token), ($token != $TOK_OPEN_BRACE)) {
319
	&ifatal ("expected '{'");
320
    }
321
    if ((($token, $data) = &next_token), ($token != $TOK_STRING)) {
322
	&ifatal ("expected tag name");
323
    }
324
    $tag_name    = $data;
325
    $munged_name = &munge_name ($tag_name);
326
    if (defined ($tag_types{$tag_name})) {
327
	&ifatal ("tag '", $tag_name, "' defined twice in error '", $name, "'");
328
    } elsif (defined ($tmp = $tag_mnames{$munged_name})) {
329
	&ifatal ("tag '", $tag_name, "' clashes with tag '", $tmp,
330
		 "' in error '", $name, "'");
331
    } elsif (defined ($tmp = $param_types{$munged_name})) {
332
	&ifatal ("tag '", $tag_name, "' clashes with parameter '",
333
		 $munged_name, "' in error '", $name, "'");
334
    }
335
    if ((($token, $data) = &next_token), ($token != $TOK_COLON)) {
336
	&ifatal ("expected ':'");
337
    }
338
    if ((($token, $data) = &next_token), ($token != $TOK_STRING)) {
339
	&ifatal ("expected tag type string");
340
    }
341
    $tag_type = $data;
342
    if ((($token, $data) = &next_token), ($token != $TOK_PROGRAM)) {
343
	&ifatal ("expected tag handling code");
344
    }
345
    $tag_code = $data;
346
    if ((($token, $data) = &next_token), ($token == $TOK_PROGRAM)) {
347
	$tag_init = $data;
348
	($token, $data) = &next_token;
349
    }
350
    if ($token != $TOK_CLOSE_BRACE) {
351
	&ifatal ("expected '}'");
352
    }
353
    if (!defined ($error_tags{$tag_name})) {
354
	$error_tags{$tag_name} = $error_tag_index ++;
355
	push (@error_tag_order, $tag_name);
356
    }
357
    $tag_types{$tag_name}     = $tag_type;
358
    $tag_mnames{$munged_name} = $tag_name;
359
    $tag_names{$tag_name}     = $munged_name;
360
    $tag_code{$tag_name}      = $tag_code;
361
    if (defined ($tag_init)) {
362
	$tag_init{$tag_name}  = $tag_init;
363
    }
364
    push (@tag_order, $tag_name);
365
}
366
 
367
sub build_structure {
368
    local ($error, *tag_types, *tag_names, *tag_order) = @_;
369
    local ($header, $def, $i, $tag, $type, $name, $indent, $tmp);
370
 
371
    if ($#tag_order) {
372
	$def = (" {\n");
125 7u83 373
	for ($i = 0; $i < $#tag_order; $i ++) {
6 7u83 374
	    $tag    = $tag_order [$i];
375
	    $type   = $tag_types{$tag};
376
	    $name   = $tag_names{$tag};
377
	    $indent = &indent_to ("    " . $type, 30);
378
	    $def   .= ("    " . $type . $indent . $name . ";\n");
379
	}
380
	$def .= "};\n";
381
	if (defined ($tmp = $error_struct_match{$def})) {
382
	    $error_struct_name{$error} = $tmp;
383
	} else {
384
	    $header = sprintf ("struct ES_%05d", $error_struct_num ++);
385
	    $error_struct_match{$def}  = $header;
386
	    $error_struct_name{$error} = $header;
387
	    push (@error_structures, ($header . $def));
388
	}
389
    }
390
}
391
 
392
sub build_tag_proc {
393
    local ($error, *tag_types, *tag_names, *tag_order, *tag_code) = @_;
394
    local ($header, $def, $i, $tag, $code, $index, $name, $struct);
395
 
396
    if (defined ($struct = $error_struct_name{$error})) {
397
	$def    = ("{\n    " . $struct . " *closure = (" . $struct .
398
		   " *)gclosure;\n\n");
125 7u83 399
	for ($i = 0; $i < $#tag_order; $i ++) {
6 7u83 400
	    $tag   = $tag_order [$i];
401
	    $name  = $tag_names{$tag};
402
	    $code  = $tag_code{$tag};
403
	    $index = $error_tags{$tag};
404
	    if ($i == 1) {
405
		$def .= ("    if (tag == ET[" . $index . "].tag) {\n");
406
	    } else {
407
		$def .= ("    } else if (tag == ET[" . $index . "].tag) {\n");
408
	    }
409
	    $def .= $code;
410
	}
411
	$def .= "    }\n}\n";
412
    } else {
413
	$def = ("{\n    UNUSED(ostream);\n" . "    UNUSED(tag);\n" .
414
		"    UNUSED(gclosure);\n}\n");
415
    }
416
    if (defined ($tmp = $error_tproc_match{$def})) {
417
	$error_tproc_name{$error} = $tmp;
418
    } else {
419
	$name   = sprintf ("ET_%05d", $error_tproc_num ++);
420
	$header = ("static void\n" . $name .
421
		   "(OStreamP ostream, ETagP tag, GenericP gclosure)\n");
422
	$error_tproc_match{$def}  = $name;
423
	$error_tproc_name{$error} = $name;
424
	push (@error_tag_procs, ($header . $def));
425
    }
426
}
427
 
428
sub build_proc_dec {
429
    local ($error, $munged_name, *tag_types, *tag_names, *tag_init, *tag_order,
430
	   *param_types, *param_order) = @_;
431
    local ($dec, $i, $tag, $type, $sep, $args, $param);
432
 
433
    $sep  = undef;
434
    $dec  = ("extern void E_" . $munged_name . "(");
435
    $args = 0;
125 7u83 436
    for ($i = 0; $i < $#param_order; $i ++) {
6 7u83 437
	$param = $param_order [$i];
438
	$type  = $param_types{$param};
439
	if (defined ($sep)) {
440
	    $dec .= $sep;
441
	}
442
	$dec .= $type;
443
	$sep  = ", ";
444
	$args ++;
445
    }
125 7u83 446
    for ($i = 0; $i < $#tag_order; $i ++) {
6 7u83 447
	$tag  = $tag_order [$i];
448
	$type = $tag_types{$tag};
449
	if (!defined ($tag_init{$tag})) {
450
	    if (defined ($sep)) {
451
		$dec .= $sep;
452
	    }
453
	    $dec .= $type;
454
	    $sep  = ", ";
455
	    $args ++;
456
	}
457
    }
458
    if ($args == 0) {
459
	$dec .= "void";
460
    }
461
    $error_proc_decs{$error} = ($dec . ");\n");
462
}
463
 
464
sub build_proc_def {
465
    local ($error, $munged_name, *tag_types, *tag_names, *tag_init,
466
	   *tag_order, *param_types, *param_order) = @_;
467
    local ($def, $tmp_def, $i, $tag, $type, $name, $col, $sep, $init, $args);
468
    local ($param, $struct, $closure);
469
 
470
    $sep     = undef;
471
    $def     = ("void\nE_" . $munged_name);
472
    $tmp_def = "";
473
    $col     = (length ($munged_name) + 2);
474
    $args    = 0;
475
    $sep     = undef;
125 7u83 476
    for ($i = 0; $i < $#param_order; $i ++) {
6 7u83 477
	$param = $param_order [$i];
478
	if (defined ($sep)) {
479
	    $tmp_def .= $sep;
480
	}
481
	$args ++;
482
    }
125 7u83 483
    for ($i = 0; $i < $#tag_order; $i ++) {
6 7u83 484
	$tag  = $tag_order [$i];
485
	$name = $tag_names{$tag};
486
	if (!defined ($tag_init{$tag})) {
487
	    if (defined ($sep)) {
488
		$tmp_def .= $sep;
489
	    }
490
	    $args ++;
491
	}
492
    }
493
    $tmp_def .= "(";
494
    $col     += 1;
495
 
496
    if ($args == 0) {
497
	$def .= "(void)\n";
498
    } else {
499
	$def .= $tmp_def;
500
	$sep  = undef;
125 7u83 501
	for ($i = 0; $i < $#param_order; $i ++) {
6 7u83 502
	    $param = $param_order [$i];
503
	    $type  = $param_types{$param};
504
	    if (defined ($sep)) {
505
		$def .= $sep;
506
	    }
507
	    $def .= ($type . " " . $param);
508
	    $sep  = (",\n" . &indent_to ("", $col));
509
	}
125 7u83 510
	for ($i = 0; $i < $#tag_order; $i ++) {
6 7u83 511
	    $tag  = $tag_order [$i];
512
	    $name = $tag_names{$tag};
513
	    $type = $tag_types{$tag};
514
	    if (!defined ($tag_init{$tag})) {
515
		if (defined ($sep)) {
516
		    $def .= $sep;
517
		}
518
		if ((length($def) + length($type) + length($name) + 1) > 78) {
519
			$def .= ($type . " " . $name);
520
#		$sep  = (",\n" . &indent_to ("", $col));
521
			$sep = (", ");
522
		} else {
523
			$sep = (",\n" . &indent_to("", $col));
524
			$def .= ($type . " " . $name);
525
		}
526
	    }
527
	}
528
	$def .= ")\n";
529
    }
530
    $def .= "{\n";
531
    if (defined ($struct = $error_struct_name{$error})) {
532
	$def .= ("    " . $struct . " closure;\n\n");
125 7u83 533
	for ($i = 0; $i < $#tag_order; $i ++) {
6 7u83 534
	    $tag  = $tag_order [$i];
535
	    $name = $tag_names{$tag};
536
	    if (defined ($init = $tag_init{$tag})) {
537
		$def .= $init;
538
	    } else {
539
		$def .= ("    closure." . $name . " = " . $name . ";\n");
540
	    }
541
	}
542
	$closure = "(GenericP)&closure";
543
    } else {
544
	$closure = "NIL(GenericP)";
545
    }
546
    $def .= ("    error_call_init_proc();\n    error_report(EE[" .
547
	     $error_index{$error} . "].error, " . $error_tproc_name{$error} .
548
	     ", " . $closure . ");\n");
549
    if (($error_severities{$error} eq "ERROR_SEVERITY_FATAL") ||
550
	($error_severities{$error} eq "ERROR_SEVERITY_INTERNAL")) {
551
	$def .= "    UNREACHED;\n";
552
    }
553
    $error_proc_defs{$error} = ($def . "}\n");
554
}
555
 
556
sub parse_error {
557
    local ($severity) = @_;
558
    local ($token, $data, $name, $munged_name);
559
    local (%tag_types, %tag_names, %tag_mnames, %tag_code, %tag_init,
560
	   @tag_order, @used_tags, $tag, %param_types, @param_order);
561
 
562
    ($name, $munged_name) = &parse_error_header ($severity, *used_tags,
563
						 *param_types, *param_order);
564
    while ((($token, $data) = &next_token), ($token == $TOK_COMMA)) {
565
	&parse_error_tag ($name, *tag_types, *tag_names, *tag_mnames,
566
			  *tag_code, *tag_init, *tag_order, *param_types);
567
    }
568
    if ($token == $TOK_PROGRAM) {
569
	$error_client_data{$name} = $data;
570
	($token, $data) = &next_token;
571
    } else {
572
	$error_client_data{$name} = "NIL(GenericP)";
573
    }
574
    if ($token != $TOK_CLOSE_BRACE) {
575
	&ifatal ("expected '}'");
576
    }
577
    foreach $tag (@used_tags) {
578
	if (!defined ($tag_types{$tag})) {
579
	    &fatal ("error '", $name, "' uses undefined tag '", $tag, "'");
580
	}
581
    }
582
    $error_index{$name} = $#error_order;
583
    &build_structure ($name, *tag_types, *tag_names, *tag_order);
584
    &build_tag_proc  ($name, *tag_types, *tag_names, *tag_order, *tag_code);
585
    &build_proc_dec  ($name, $munged_name, *tag_types, *tag_names, *tag_init,
586
		      *tag_order, *param_types, *param_order);
587
    &build_proc_def  ($name, $munged_name, *tag_types, *tag_names, *tag_init,
588
		      *tag_order, *param_types, *param_order);
589
    push (@error_order, $name);
590
}
591
 
592
sub parse_header {
593
    local ($token, $data);
594
 
595
    if ((($token, $data) = &next_token), ($token != $TOK_PROGRAM)) {
596
	&ifatal ("expected program section");
597
    }
598
    $error_header .= ("/* Header from input file '" . $infile . "' */\n" .
599
		      $data . "\n");
600
}
601
 
602
sub parse_c_header {
603
    local ($token, $data);
604
 
605
    if ((($token, $data) = &next_token), ($token != $TOK_PROGRAM)) {
606
	&ifatal ("expected program section");
607
    }
608
    $error_c_header .= ("/* Header from input file '" . $infile . "' */\n" .
609
			$data . "\n");
610
}
611
 
612
sub parse_file {
613
    local ($file) = @_;
614
 
615
    &reset_lexer ($file);
616
    while ((($token, $data) = &next_token), ($token != $TOK_EOF)) {
617
	if ($token == $TOK_HEADER) {
618
	    &parse_header;
619
	} elsif ($token == $TOK_C_HEADER) {
620
	    &parse_c_header;
621
	} elsif ($token == $TOK_SEVERITY) {
622
	    &parse_error ($data);
623
	} else {
624
	    &ifatal ("expected header or severity level");
625
	}
626
	if ((($token, $data) = &next_token), ($token != $TOK_SEMI_COLON)) {
627
	    &ifatal ("expected ';'");
628
	}
629
    }
630
    close (INFILE);
631
}
632
 
633
###############################################################################
634
### Output:
635
 
636
sub output_c_file {
637
    local ($i, $tag, $error, $name);
638
 
639
    print OUTFILE ("/* Automatically generated by '", $prog, "' */\n\n");
640
    print OUTFILE ("#include \"", &basename ($outfile), ".h\"\n");
641
    print OUTFILE ("#include \"error.h\"\n");
642
    print OUTFILE ("#include \"ostream.h\"\n\n");
643
    print OUTFILE ($error_c_header, "\n");
644
 
645
    print OUTFILE ("static ETagDataT ET[] = {\n");
125 7u83 646
    for ($i = 0; $i < $#error_tag_order; $i ++) {
6 7u83 647
	$tag = $error_tag_order [$i];
648
	print OUTFILE ("    UB \"", $tag, "\" UE,\n");
649
    }
650
    print OUTFILE ("    ERROR_END_TAG_LIST\n");
651
    print OUTFILE ("};\n\n");
652
 
653
    print OUTFILE ("static ErrorDataT EE[] = {\n");
125 7u83 654
    for ($i = 0; $i < $#error_order; $i ++) {
6 7u83 655
	$error = $error_order [$i];
656
	print OUTFILE ("    UB {\n\t\"", $error, "\",\n\t",
657
		       $error_severities{$error}, ",\n\t\"",
658
		       $error_messages{$error}, "\",\n\t",
659
		       $error_client_data{$error}, "\n    } UE,\n");
660
    }
661
    print OUTFILE ("    ERROR_END_ERROR_LIST\n");
662
    print OUTFILE ("};\n\n");
663
 
125 7u83 664
    for ($i = 0; $i < $#error_structures; $i ++) {
6 7u83 665
	print OUTFILE ($error_structures [$i]);
666
    }
667
    print OUTFILE ("\n");
668
 
125 7u83 669
    for ($i = 0; $i < $#error_tag_procs; $i ++) {
6 7u83 670
	print OUTFILE ($error_tag_procs [$i]);
671
    }
672
    print OUTFILE ("\n");
673
 
125 7u83 674
    for ($i = 0; $i < $#error_order; $i ++) {
6 7u83 675
	$error = $error_order [$i];
676
	print OUTFILE ($error_proc_defs{$error});
677
    }
678
    $name = &munge_name (&basename ($outfile));
679
    print OUTFILE ("\nvoid\n", $name, "_init_errors(void)\n",
680
		   "{\n    error_intern_tags (ET);\n",
681
		   "    error_intern_errors (EE);\n}\n");
682
}
683
 
684
sub output_h_file {
685
    local ($i);
686
 
687
    print OUTFILE ("/* Automatically generated by '", $prog, "' */\n\n");
688
    print OUTFILE ("#include \"os-interface.h\"\n\n");
689
    print OUTFILE ($error_header, "\n");
690
 
691
    print OUTFILE ("/* Error function declarations */\n\n");
125 7u83 692
    for ($i = 0; $i < $#error_order; $i ++) {
6 7u83 693
	$error = $error_order [$i];
694
	print OUTFILE ($error_proc_decs{$error});
695
    }
696
    print OUTFILE ("\nextern void ", &munge_name (&basename ($outfile)),
697
		   "_init_errors(void);\n");
698
}
699
 
700
###############################################################################
701
 
702
$outfile	= "error-mesgs";
703
 
704
###############################################################################
705
 
706
arg:
707
while (defined ($arg = shift (@ARGV))) {
708
    if ($arg =~ /^-o/) {
709
	(defined ($outfile = shift (@ARGV))) ||
710
	    &fatal ("no output file name specified after '", $arg, "' option");
711
    } elsif ($arg =~ /^-/) {
712
	&fatal ("unknown option '", $arg, "'");
713
    } else {
714
	unshift (@ARGV, $arg);
715
	last arg;
716
    }
717
}
718
 
719
while (defined ($infile = shift (@ARGV))) {
720
    &parse_file ($infile);
721
}
722
 
723
open (OUTFILE, ">" . $outfile . ".c") ||
724
    &fatal ("cannot open output file '", $outfile, ".c'");
725
&output_c_file;
726
close (OUTFILE);
727
open (OUTFILE, ">" . $outfile . ".h") ||
728
    &fatal ("cannot open output file '", $outfile, ".h'");
729
&output_h_file;
730
close (OUTFILE);
731
exit (0);