Subversion Repositories tendra.SVN

Rev

Details | Last modification | View Log | RSS feed

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