Subject: Re: Protecting the rest of the kerner headers against multiple inclusion
To: Christos Zoulas <christos@zoulas.com>
From: Simon J. Gerraty <sjg@quick.com.au>
List: tech-kern
Date: 09/13/1999 17:57:29
> | does not already protect itself), it would look nicer, though perhaps
> | be less efficient to put the #ifndef _SYS_TYPES_H_ before the first
> | non-comment line?
>
> Dunno, I like them where they are now I guess, where it is after the
> copyright.
Ok, here's the perl version which does the right thing wrt comments.
#!/usr/bin/env perl
# NAME:
# chprot - protect C headers from themselves
#
# SYNOPSIS:
# chprot.pl [options] *.h
# find . -name '*.h' -print | chprot.pl [options]
#
# DESCRIPTION:
# Ensure C headers protect themselves against multiple
# inclusion.
#
# We first attempt to check if the header is already
# protected. If not we generate a tag to protect it that
# will hopefully be unique such as:
#.nf
#
# stdio.h _STDIO_H_
# sys/types.h _SYS_TYPES_H_
#.fi
#
# The the first non-empty, non-comment line of the header to the
# end of file is then enclosed by:
#.nf
#
# #ifndef $tag
# # define $tag
# <original header>
# #endif /* $tag */
#.fi
#
# Options:
#
# -l Use lower case tags.
#
# -v Be verbose, tell us what is going on.
#
# AUTHOR:
# Simon J. Gerraty <sjg@quick.com.au>
#
$RCSid = '$Id: chprot.pl,v 1.2 1999/09/13 07:55:13 sjg Exp $'; # emacs'
#
# @(#)Copyright (c) 1991 Simon J. Gerraty
#
# This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY.
# Permission to copy, redistribute or otherwise
# use this file is hereby granted provided that
# the above copyright notice and this notice are
# left intact.
#
# Please send copies of changes and bug-fixes to:
# sjg@quick.com.au
#
require 'getopts.pl';
&Getopts('vd');
sub show {
local($flag,@args) = @_;
if ($flag ne '') {
printf STDERR @args;
}
}
sub protect {
local($hdr) = @_;
if ($hdr =~ m,/assert.h,) {
&show(1, "skipping $hdr\n");
return;
}
$tag = $hdr;
$tag =~ s,.*include,,;
$tag =~ y,a-z\./,A-Z__,;
$tag = "_${tag}_";
$tag =~ s,__+,_,g;
$tag =~ y/A-Z/a-z/ if ($opt_l ne '');
# first see if there is some attempt at protecting it already.
$check = $tag;
$check =~ s/.*(_[^_]+_H)_*$/$1/;
chop($ok = `grep -i "#[ \t]*if.*def.*$check" $hdr`);
if ($ok ne '') {
&show("$opt_d$opt_v", "$hdr protected by $ok\n");
return;
}
if (open(H, "< $hdr")) {
if (open(N, "> $hdr.new")) {
$protected = 0;
$comment = 0;
&show("$opt_d$opt_v", "$hdr protecting with $tag\n");
while (<H>) {
if (m,^\s*/\*.*\*/,) {
print N;
next;
} elsif (m,^\s*/\*,) {
$comment = 1;
print N;
next;
} elsif (m,\*/,) {
$comment = 0;
print N;
next;
} elsif (m/^\s*$/) {
print N;
next;
} else {
if (!$protected && !$comment) {
print N "#ifndef $tag\n# define $tag\n\n";
$protected = 1;
}
print N;
}
}
if ($protected) {
print N "\n#endif /* $tag */\n";
}
close N;
close H;
rename($hdr, "$hdr.bak");
rename("$hdr.new", $hdr);
} else {
close H;
}
}
}
sub main {
if (scalar(@ARGV) > 0) {
foreach $hdr (@ARGV) {
&protect($hdr);
}
} else {
while (<STDIN>) {
chop;
&protect($_);
}
}
}
&main;
exit 0;