3 ## $Id: buildconfig.in 6806 2004-05-18 01:18:57Z rra $
5 ## Generate linkage code and makefiles for storage and overview methods.
7 ## Goes through all subdirectories of the current directory and finds
8 ## directories that history methods or overview methods. Builds
9 ## hismethods.[ch] as well as makefile stubs.
14 use vars qw(@HISTORY);
16 # History API functions.
17 @HISTORY = qw(open close sync lookup check write replace expire walk remember
20 # Used to make heredocs more readable.
21 sub unquote { my ($string) = @_; $string =~ s/^:( {0,7}|\t)//gm; $string }
23 # Parse a hismethod.config file for a history method, putting information
24 # about that history method into the given hash ref.
26 my ($dir, $file, $config) = @_;
28 $$config{sources} ||= [];
29 $$config{extra} ||= [];
30 $$config{programs} ||= [];
31 $$config{makefiles} ||= [];
32 open (CONFIG, "$dir/$file") or die "Can't open $dir/$file: $!\n";
36 if (/^name\s*=\s*(\S+)$/) {
38 die "$dir/$file: $method has already been defined\n"
39 if (defined $$config{method}{$method});
40 $$config{method}{$method} = $dir;
41 } elsif (/^number\s*=\s*(\d+)$/) {
43 if (defined $$config{number}{$number}) {
44 die "$dir/$file: method number $number was already "
45 . "allocated in $$config{number}{$number}\n";
47 $$config{number}{$dir} = $number;
48 } elsif (/^sources\s*=\s*(.*)/) {
50 my @sources = split (' ', $sources);
51 push (@{ $$config{sources} }, map { "$dir/$_" } @sources);
52 } elsif (/^extra-sources\s*=\s*(.*)/) {
54 my @extra = split (' ', $extra);
55 push (@{ $$config{extra} }, map { "$dir/$_" } @extra);
56 } elsif (/^programs\s*=\s*(.*)/) {
58 my @programs = split (' ', $programs);
59 push (@{ $$config{programs} }, map { "$dir/$_" } @programs);
61 warn "$dir/$file: ignoring unknown line: $_\n";
65 # If there is a makefile fragment in the directory, note it.
66 if (-f "$dir/hismethod.mk") {
67 push (@{ $$config{makefiles} }, "$dir/hismethod.mk");
71 # Write out include directives for a list of files.
73 my ($fh, $config) = @_;
75 for $method (sort keys %{ $$config{method} }) {
76 my $path = $$config{method}{$method};
77 print $fh qq(\#include "$path/$method.h"\n);
81 # Write out the method struct.
83 my ($fh, $config, $prefix, @funcs) = @_;
84 my ($notfirst, $method);
85 for $method (sort keys %{ $$config{method} }) {
86 print $fh "\n},\n" if $notfirst;
87 print $fh qq(\{\n "$method");
88 print $fh ', ', $prefix, '_', uc ($method) if $prefix;
90 print $fh ",\n ${method}_$_";
94 print $fh "\n}\n};\n\n";
97 # Write out hismethods.c and hismethods.h for the interface to the history
101 open (DEF, '> hismethods.c.new')
102 or die "Can't create hismethods.c.new: $!\n";
103 print DEF unquote (<<'EOE');
104 : /* This file is automatically generated by buildconfig. */
106 : #include "hisinterface.h"
107 : #include "hismethods.h"
110 write_includes (\*DEF, $history);
111 print DEF "\nHIS_METHOD his_methods[",
112 scalar (keys %{ $$history{method} }), "] = {\n";
113 write_methods (\*DEF, $history, undef, @HISTORY);
115 rename ('hismethods.c.new', 'hismethods.c');
117 open (H, '> hismethods.h.new') or die "Can't open hismethods.h.new: $!\n";
118 print H unquote (<<'EOE');
119 : /* This file is automatically generated by buildconfig */
121 : #ifndef HISMETHODS_H
122 : #define HISMETHODS_H 1
124 : #include "hisinterface.h"
127 print H '#define NUM_HIS_METHODS ',
128 scalar (keys %{ $$history{method} }), "\n";
129 print H unquote (<<'EOE');
131 : extern HIS_METHOD his_methods[NUM_HIS_METHODS];
133 : #endif /* HISMETHODS_H */
136 rename ('hismethods.h.new', 'hismethods.h');
139 # Return a string setting a makefile variable. Tab over the = properly and
140 # wrap to fit our coding standards.
142 my ($variable, @values) = @_;
144 $output = sprintf ("%-15s =", $variable);
147 if ($column > 17 && 77 - $column < length ($_)) {
148 $output .= " \\\n" . ' ' x 17;
152 $column += 1 + length ($_);
158 # Write out the makefile fragment for history methods.
160 my ($dirs, $sources, $extra, $programs, $makefiles) = @_;
161 open (MAKE, '> Make.methods.new')
162 or die "Can't create Make.methods.new: $!\n";
163 print MAKE "# This file is automatically generated by buildconfig\n\n";
164 print MAKE makefile_var ('METHOD_SOURCES', @$sources);
165 print MAKE makefile_var ('EXTRA_SOURCES', @$extra);
166 print MAKE makefile_var ('PROGRAMS', @$programs);
168 print MAKE "\n\n## Included from $_\n\n";
169 open (FRAG, $_) or die "Can't open $_: $!\n";
173 rename ('Make.methods.new', 'Make.methods');
178 if (-d 'history/cnfs') {
179 chdir 'history' or die "Can't chdir to history: $!\n";
181 die "Can't find history directory (looking for history/hisv6)\n";
184 opendir (D, ".") or die "Can't open current directory: $!\n";
185 my @dirs = sort readdir D;
187 if (-e "$dir/hismethod.config") {
188 parse_config ($dir, 'hismethod.config', \%history);
191 write_history (\%history);
192 @dirs = sort values %{ $history{method} };
193 my @sources = sort @{ $history{sources} };
194 my @extra = sort @{ $history{extra} };
195 my @programs = sort @{ $history{programs} };
196 my @makefiles = sort @{ $history{makefiles} };
197 write_makefile (\@dirs, \@sources, \@extra, \@programs, \@makefiles);