#!/sw/bin/perl5 -w
# alter the path above to the result of `which perl` on your system

# usage: cgal_conditional_include file1 ...

# Author: Geert-Jan Giezeman.

# Protects CGAL and other include directives in the following way:

#   #ifndef CGAL_HANDLE_H
#   #include <CGAL/Handle>
#   #endif
#
# is converted to
#
#   #include <CGAL/Handle>

#   #ifndef CGAL_PROTECT_STDLIB_H
#   #include <stdlib.h>
#   #define CGAL_PROTECT_STDLIB_H
#   #endif
#
# is converted to
#
#   #include <stdlib.h>

use strict;

my $protect_name;
my $suffix;

my $tmpfilename = "CondIncl$$";
my $filename;
my $skipped = 0;

FILE:
foreach $filename (@ARGV) {
    if (!open(INFILE, $filename)) {
	print STDERR "Could not open ${filename} for reading\n$!\n";
	next FILE;
    }
    open(TMPFILE, ">$tmpfilename")
	    || die "Could not open temp file for writing\n$!\n";
    my $last = '';
    Line:
    while (<INFILE>) {
	if (($protect_name,$suffix) =
	       	m|^[\s]*#[\s]*ifndef[\s]+CGAL_PROTECT_(.*?)(_H)?\b|)  
	{
            my $protect_line = $_;
	    $_ = <INFILE>;
	    my $include_file;
	    if ( !(($include_file) =
		m|^[\s]*#[\s]*include[\s]*<(.*?)(?:\.h)?>[\s]*|)) {
		  warn "'#include <...>' missing in line ",
		  	$.-$skipped," ($filename)\n";
		  print TMPFILE $protect_line;
		  redo;
            }
	    my $include_line = $_;
	    $include_file =~ s'/'_'g;
	    $include_file =~ tr/a-z/A-Z/;
	    if ($include_file ne $protect_name) {
		warn "'#ifndef CGAL_PROTECT_$protect_name$suffix'",
	       		" followed by non corresponding #include in line ",
			$.-$skipped," ($filename)\n";
		  print TMPFILE $protect_line;
		  print TMPFILE $include_line;
		  next;
	    }
	    $_ = <INFILE>;
	    my $protect_name2;
	    if (!(($protect_name2) =
	       	m|^[\s]*#[\s]*define[\s]+CGAL_PROTECT_(.*?)(?:_H)?[\s]*$|)) {
		  warn "'#define CGAL_PROTECT_$protect_name$suffix' missing in line ",
		  	$.-$skipped," ($filename)\n";
		print TMPFILE $protect_line;
		print TMPFILE $include_line;
		redo;
	    }
	    my $protect_line2 = $_;
	    if ($protect_name2 ne $protect_name) {
		warn "'#ifndef CGAL_PROTECT_$protect_name$suffix' lacks  ",
			"'#define CGAL_PROTECT_$protect_name$suffix' in line ",
		  	$.-$skipped," ($filename)\n";
		print TMPFILE $protect_line;
		print TMPFILE $include_line;
		print TMPFILE $protect_line2;
		next;
	    }
	    $_ = <INFILE>;
	    if ( ! m|^[\s]*#[\s]*endif|) {
		warn "'#ifndef CGAL_PROTECT_$protect_name$suffix' lacks  ",
			"'#endif' in line ", $.-$skipped," ($filename)\n";
		print TMPFILE $protect_line;
		print TMPFILE $include_line;
		print TMPFILE $protect_line2;
		redo;
	    }
	    print TMPFILE $include_line;
	    $skipped += 3;
	}
       	elsif ((($protect_name,$suffix) =
	       	m|^[\s]*#[\s]*ifndef[\s]+CGAL_(.*?)(_H)?[\s]*$|)) 
       	{
            my $protect_line;
            $protect_line = $_;
	    $_ = <INFILE>;
	    my $include_file;
	    if ( !(($include_file) =
		m|^[\s]*#[\s]*include[\s]*<CGAL\/(.*?)(?:\.h)?>[\s]*|)) {
		  print TMPFILE $protect_line;
		  redo;
            }
	    my $include_line = $_;
	    $include_file =~ s'/'_'g;
	    $include_file =~ tr/a-z/A-Z/;
	    if ($include_file ne $protect_name) {
		warn "'#ifndef CGAL_$protect_name$suffix'",
	       		" followed by non corresponding #include in line ",
			$.-$skipped," ($filename)\n";
		  print TMPFILE $protect_line;
		  print TMPFILE $include_line;
		  next;
	    }
	    $_ = <INFILE>;
	    if ( ! m|^[\s]*#[\s]*endif|) {
		warn "'#ifndef CGAL_$protect_name$suffix' lacks  ",
			"'#endif' in line ", $.-$skipped," ($filename)\n";
		print TMPFILE $protect_line;
		print TMPFILE $include_line;
		redo;
	    }
	    print TMPFILE $include_line;
	    $skipped += 2;
	} else
	{
	    # copy other lines
	    print TMPFILE $_;
	}
    }
    close INFILE;
    close TMPFILE;
    if ($?) {
	print STDERR "Conversion of ${filename} failed\n$!\n";
	next FILE;
    }
    if (!rename($tmpfilename,${filename})) {
	print STDERR "Cannot rename $tmpfilename to ${filename}.\n$!\n";
	print STDERR "Conversion of ${filename} failed\n";
    }
}


syntax highlighted by Code2HTML, v. 0.9.1