#! /usr/bin/perl -w

# This program preprocesses #if's of the form:
# #if LINUX_VERSION_CODE > KERNEL_VERSION ( ?, ?, ??)
# #if LINUX_VERSION_CODE < KERNEL_VERSION ( ?, ?, ??)
#
# To be used to clean up code before submission to the kernel.
#
# - Joe Thornber

$kver = shift() || die("Usage: select_version [kernel_version]\n");
if($kver !~ /([0-9]+)\.([0-9]+)\.([0-9]+)/) {
    die("Please give kernel version in form #.#.## eg., 2.4.12\n");
}
($k1, $k2, $k3) = ($1, $2, $3);

@in_section = ();
@choose_section = ();
$depth = 0;
while(<STDIN>) {
    if(/\s*\#\s*if/) {
	$depth++;
	if(/\s*\#\s*if\s+LINUX_VERSION_CODE\s+((<)|(>)|(>=)|(<=)|(==))\s+
	   KERNEL_VERSION\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)/x) {
	    next if(scalar(@in_section) && !$choose_section[$#choose_section]);
	    push @in_section, $depth;

	    $cmp = &cmp_kver($7, $8, $9);
	    $choose = 0;
  	    if($1 eq '<' && $cmp == -1) {$choose = 1;}
  	    if($1 eq '>' && $cmp == 1) {$choose = 1;}
  	    if($1 eq '==' && $cmp == 0) {$choose = 1;}
  	    if($1 eq '<=' && ($cmp == -1 || $cmp == 0)) {$choose = 1;}
  	    if($1 eq '>=' && ($cmp == 1 || $cmp == 0)) {$choose = 1;}

	    push @choose_section, $choose;
	    next;
	}
    } elsif(/\s*\#\s*else/) {
	if(scalar(@in_section) &&
	   ($depth == $in_section[$#in_section])) {
	    $choose_section[$#choose_section] =
		!$choose_section[$#choose_section];
	    next;
	}
    } elsif(/\s*\#\s*endif/) {
	$depth--;
	if(scalar(@in_section) &&
	   ($depth < $in_section[$#in_section])) {
	    pop @in_section;
	    pop @choose_section;
	    next;
	}
    }
    print if(!scalar(@in_section) || $choose_section[$#choose_section]);
}

sub cmp_kver {
    ($v1, $v2, $v3) = @_;
    if($v1 < $k1) {return 1;}
    if($v1 > $k1) {return -1;}
    if($v2 < $k2) {return 1;}
    if($v2 > $k2) {return -1;}
    if($v3 < $k3) {return 1;}
    if($v3 > $k3) {return -1;}
    return 0;
}
