Subversion Repositories tendra.SVN

Rev

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

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