1#!/usr/bin/perl -w 2#- 3# Copyright (c) 2004 Dag-Erling Coïdan 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# $FreeBSD$ 30# 31 32use strict; 33use Getopt::Std; 34 35sub EMPTY() {} 36 37MAIN:{ 38 my %opts; 39 getopts('c', \%opts); 40 41 my %config; 42 my $machine; 43 my $ident; 44 45 while (<>) { 46 chomp(); 47 s/\s*(\#.*)?$//; 48 next unless $_; 49 my ($keyword, $values) = split(' ', $_, 2); 50 foreach my $value (split(/,\s*/, $values)) { 51 if ($keyword eq 'machine') { 52 $machine = $value; 53 } elsif ($keyword eq 'ident') { 54 $ident = $value; 55 } elsif ($keyword eq 'options' && $value =~ m/(\w+)=(.+)/) { 56 $config{$keyword}->{$1} = $2; 57 } else { 58 $config{$keyword}->{$value} = \&EMPTY; 59 } 60 } 61 } 62 63 my $generic; 64 if ($machine) { 65 $generic = "/usr/src/sys/$machine/conf/GENERIC"; 66 } else { 67 ($generic = $ARGV) =~ s|([^/])+$|GENERIC|; 68 } 69 local *GENERIC; 70 open(GENERIC, "<", $generic) 71 or die("$generic: $!\n"); 72 my $blank = 0; 73 while (<GENERIC>) { 74 my $line = $_; 75 chomp(); 76 if ($opts{'c'} && m/^\s*\#/) { 77 if ($blank) { 78 print "\n"; 79 $blank = 0; 80 } 81 print $line; 82 next; 83 } 84 ++$blank unless $_; 85 s/\s*(\#.*)?$//; 86 next unless $_; 87 my ($keyword, $value) = split(' ', $_); 88 if ($keyword eq 'machine') { 89 die("$generic is for $value, not $machine\n") 90 unless ($value eq $machine); 91 } elsif ($keyword eq 'ident') { 92 $line =~ s/$value/$ident/; 93 } elsif ($keyword eq 'options' && $value =~ m/(\w+)=(.+)/ && 94 $config{$keyword} && $config{$keyword}->{$1} && 95 $config{$keyword}->{$1} != \&EMPTY) { 96 $value = $1; 97 if ($config{$keyword}->{$value} ne $2) { 98 my ($old, $new) = ($2, $config{$keyword}->{$value}); 99 $line =~ s{=$old}{=$new}; 100 } 101 delete($config{$keyword}->{$value}); 102 delete($config{$keyword}) 103 unless %{$config{$keyword}}; 104 } elsif ($config{$keyword} && $config{$keyword}->{$value}) { 105 delete($config{$keyword}->{$value}); 106 delete($config{$keyword}) 107 unless %{$config{$keyword}}; 108 } else { 109 next; 110 } 111 if ($blank) { 112 print "\n"; 113 $blank = 0; 114 } 115 print $line; 116 } 117 close(GENERIC); 118 119 if (%config) { 120 print "\n# Addenda\n"; 121 foreach my $keyword (sort(keys(%config))) { 122 foreach my $value (sort(keys(%{$config{$keyword}}))) { 123 print "$keyword"; 124 if (length($keyword) < 7) { 125 print "\t"; 126 } elsif (length($keyword) == 7) { 127 print " "; 128 } 129 print "\t$value"; 130 print "=$config{$keyword}->{$value}" 131 unless $config{$keyword}->{$value} == \&EMPTY; 132 print "\n"; 133 } 134 } 135 } 136 exit(0); 137} 138