1#!/usr/bin/perl
2
3use Getopt::Std;
4
5# xpostconf - extract parameter info from postconf prototype file
6
7# Usage: xpostconf [options] protofile [parameter...]
8#
9# -b: Brief output: print only the first sentence of each definition
10#
11# -c: print the classes named on the command line (default: all).
12#
13# -h: print help message.
14#
15# -p: print the parameters named on the command line (default: all).
16#
17# -s specfile: process the entries listed in the named file: ordinary
18# text is copied as is,
19#	%CLASS class-name mode
20#	%PARAM param-name mode
21# are replaced by the respective information. Mode is b (brief)
22# f (full) or i (ignore).
23#
24# If no -s is specified, extracts the named parameter text (all
25# parameters by default).
26
27$opt_b = undef;
28$opt_c = undef;
29$opt_p = undef;
30$opt_s = undef;
31$opt_v = undef;
32getopts("bcps:v");
33
34die "Usage: $0 [-bcpv] [-s specfile] protofile [parameter...]\n"
35	unless $protofile = shift(@ARGV);
36
37# Save one definition.
38
39sub save_text {
40    if ($category eq "PARAM") {
41	$param_text{$name} = $text;
42	if ($opt_v) {
43	    printf "saving entry %s %.20s..\n", $name, $text;
44	}
45    } elsif ($category eq "CLASS") {
46	$class_text{$name} = $text;
47	if ($opt_v) {
48	    printf "saving class %s %.20s..\n", $name, $text;
49	}
50    } else {
51	die "Unknown category: $category. Need PARAM or CLASS.\n";
52    }
53}
54
55# Read the whole file even if we want to print only one parameter.
56
57open(POSTCONF, $protofile) || die " cannot open $protofile: $!\n";
58
59while(<POSTCONF>) {
60
61    next if /^#/ && $text eq "";
62    next unless ($name || /\S/);
63
64    if (/^%(PARAM|CLASS)/) {
65
66	# Save the accumulated text.
67
68	if ($name && $text) {
69	    save_text();
70	}
71
72	# Reset the parameter name and accumulated text.
73
74	$name = $text = "";
75	$category = $1;
76
77	# Accumulate the parameter name and default value.
78
79	do {
80	    $text .= $_;
81	} while(($_ = <POSTCONF>) && /\S/);
82	($junk, $name, $junk) = split(/\s+/, $text, 3);
83
84    }
85
86    # Accumulate the text in the class or parameter definition.
87
88    $text .= $_;
89
90}
91
92# Save the last definition.
93
94if ($name && $text) {
95    save_text();
96}
97
98# If working from a spec file, emit output in the specified order.
99
100if ($opt_s) {
101    open(SPEC, "$opt_s") || die "cannot open $opt_s: $!\m";
102    while(<SPEC>) {
103	if (/^%/) {
104	    ($category, $name, $mode) = split(/\s+/, substr($_, 1));
105	    if ($category eq "CLASS") {
106		die "Unknown class name: $name.\n"
107		    unless $text = $class_text{$name};
108	    } elsif ($category eq "PARAM") {
109		die "Unknown parameter name: $name.\n"
110		    unless $text = $param_text{$name};
111	    } else {
112		die "Unknown category: $category. Need CLASS or PARAM\n";
113	    }
114	    if ($mode eq "i") {
115		next;
116	    } elsif ($mode eq "b") {
117		$text =~ s/\.\s.*/.\n\n/s;
118	    } elsif ($mode ne "p") {
119		die "Unknown mode: $mode. Need b or p or i,\n";
120	    }
121	    print $text, "\n";
122	} else {
123	    print;
124	}
125    }
126    exit;
127}
128
129# Print all the parameters.
130
131if ($opt_c) {
132    $what = \%class_text;
133} else {
134    $what = \%param_text;
135}
136
137if ($#ARGV < 0) {
138    for $name (sort keys %{$what}) {
139	$text = ${$what}{$name};
140	$text =~ s/\.\s.*/.\n\n/s if ($opt_b);
141	print $text, "\n";
142    }
143}
144
145# Print parameters in the specified order.
146
147else {
148    for $name (@ARGV) {
149	$text = ${$what}{$name};
150	$text =~ s/\.\s.*/.\n\n/s if ($opt_b);
151	print $text;
152    }
153}
154