1#!/usr/bin/perl -w 2#- 3# Copyright (c) 2004 Dag-Erling Sm��rgrav 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer 11# in this position and unchanged. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 3. The name of the author may not be used to endorse or promote products 16# derived from this software without specific prior written permission. 17# 18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28# 29# 30 31use strict; 32use Getopt::Std; 33 34sub EMPTY() {} 35 36MAIN:{ 37 my %opts; 38 getopts('c', \%opts); 39 40 my %config; 41 my $machine; 42 my $ident; 43 44 while (<>) { 45 chomp(); 46 s/\s*(\#.*)?$//; 47 next unless $_; 48 my ($keyword, $values) = split(' ', $_, 2); 49 foreach my $value (split(/,\s*/, $values)) { 50 if ($keyword eq 'machine') { 51 $machine = $value; 52 } elsif ($keyword eq 'ident') { 53 $ident = $value; 54 } elsif ($keyword eq 'options' && $value =~ m/(\w+)=(.+)/) { 55 $config{$keyword}->{$1} = $2; 56 } else { 57 $config{$keyword}->{$value} = \&EMPTY; 58 } 59 } 60 } 61 62 my $generic; 63 if ($machine) { 64 $generic = "/usr/src/sys/$machine/conf/GENERIC"; 65 } else { 66 ($generic = $ARGV) =~ s|([^/])+$|GENERIC|; 67 } 68 local *GENERIC; 69 open(GENERIC, "<", $generic) 70 or die("$generic: $!\n"); 71 my $blank = 0; 72 while (<GENERIC>) { 73 my $line = $_; 74 chomp(); 75 if ($opts{'c'} && m/^\s*\#/) { 76 if ($blank) { 77 print "\n"; 78 $blank = 0; 79 } 80 print $line; 81 next; 82 } 83 ++$blank unless $_; 84 s/\s*(\#.*)?$//; 85 next unless $_; 86 my ($keyword, $value) = split(' ', $_); 87 if ($keyword eq 'machine') { 88 die("$generic is for $value, not $machine\n") 89 unless ($value eq $machine); 90 } elsif ($keyword eq 'ident') { 91 $line =~ s/$value/$ident/; 92 } elsif ($keyword eq 'options' && $value =~ m/(\w+)=(.+)/ && 93 $config{$keyword} && $config{$keyword}->{$1} && 94 $config{$keyword}->{$1} != \&EMPTY) { 95 $value = $1; 96 if ($config{$keyword}->{$value} ne $2) { 97 my ($old, $new) = ($2, $config{$keyword}->{$value}); 98 $line =~ s{=$old}{=$new}; 99 } 100 delete($config{$keyword}->{$value}); 101 delete($config{$keyword}) 102 unless %{$config{$keyword}}; 103 } elsif ($config{$keyword} && $config{$keyword}->{$value}) { 104 delete($config{$keyword}->{$value}); 105 delete($config{$keyword}) 106 unless %{$config{$keyword}}; 107 } else { 108 next; 109 } 110 if ($blank) { 111 print "\n"; 112 $blank = 0; 113 } 114 print $line; 115 } 116 close(GENERIC); 117 118 if (%config) { 119 print "\n# Addenda\n"; 120 foreach my $keyword (sort(keys(%config))) { 121 foreach my $value (sort(keys(%{$config{$keyword}}))) { 122 print "$keyword"; 123 if (length($keyword) < 7) { 124 print "\t"; 125 } elsif (length($keyword) == 7) { 126 print " "; 127 } 128 print "\t$value"; 129 print "=$config{$keyword}->{$value}" 130 unless $config{$keyword}->{$value} == \&EMPTY; 131 print "\n"; 132 } 133 } 134 } 135 exit(0); 136} 137