#!/usr/bin/perl

# Mandrake Graphic Install
# Copyright (C) 1999 Mandrakesoft (fpons@mandrakesoft.com)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

$srctop = $ARGV[0];

unless (-d $srctop) {
  print STDERR "usage: $0 <linux_src_top>\n";
  print STDERR "   <linux_src_top> is the linux source top directory,\n";
  print STDERR "                   for example /usr/src/linux\n";
  exit 1;
}

open (FILE_LIST, "find $srctop/ -name \"*.c\" |");

while (<FILE_LIST>) {
  chomp;

  my $file = $_;
  my $dir = $file;
  my $module = $file;
  my $incfile;
  my @incfiles;
  my %parms;
  my $oldline;
  my $descline;
  my $default;
  my %substvars;

  # get mormalized directory name.
  $dir =~ s/^(.*)\/[^\/]*$/$1/;

  # get mormalized module name.
  $module  =~ s/^.*\/([^\/]*)\.c$/$1/;

  # search for recogniwed special keywords.
  open (F, $file);
  while (<F>) {
    # track for include files.
    if (/^\#\s*include\s+[\<\"]([\w-\.\/]*)[\"\>]/) {
      # search from /usr/src/linux/include directory.
      push @incfiles, "/usr/src/linux/include/$1";

      # search from current working directory.
      push @incfiles, "$dir/$1";
    }

    if (/^\s*MODULE_PARM\s*\((\w*)\s*,\s*\"/) {
	$parms{$1}{type} = '?';
    }
    if (/^\s*MODULE_PARM\s*\((\w*)\s*,\s*\"([^\"]*)\"\s*\)/) {
      $parms{$1}{type} = $2;
    }
    if (/^\s*MODULE_PARM_DESC\s*\((\w*)\s*,\s*\"([^\"]*)\"\s*\)/) {
      $parms{$1}{desc} = $2;
    }
  }
  close F;

  # parse associated include file if exist.
  foreach $incfile (@incfiles) {
    if (-r $incfile) {
      open (F, $incfile);
      while (<F>) {
	s/^(.*)\/\*.*$/$1/g;
	if (/^\#\s*define\s*(\w*)\s*(.*)$/) {
	  $substvars{$1}=$2;
	}
      }
      close F;
    }
  }

  # search for comments about each module parameter.
  open (F, $file);
  while (<F>) {
    my $line = $_;

    # manage simple preprocessor.
    s/^(.*)\/\*.*$/$1/g;
    if (/^\#\s*define\s*(\w*)\s*(.*)$/) {
      $substvars{$1}=$2;
    }

    # parse for parameters definition.
    foreach $parm (keys %parms) {
      if ($line =~ /^\s*(static\s+)?((short|long|signed|unsigned)\s+)?\w+(\s*\**\s+|\s+\**\s*)$parm(\s*\[.*\]\s*)?\s*=\s*([^\;]*)\;/) {
	$default = $descline = $6;
	$default =~ s/^(.*)\/\*.*$/$1/g;

	# remove hypothetic couple of { }.
	$default =~ s/^(\s*\{\s*)(.*)(\s*\}\s*)$/$2/;

	# subsitute variable.
	foreach $substvar (keys %substvars) {
	  $default =~ s/$substvar/$substvars{$substvar}/g;
	}
	$default =~ s/NULL/0/g;
	$default =~ s/^\s*(.*?)\s*$/$1/;
	$default = '' if $default =~ /\(\s*\(\s*void*\s*\*\)\s*0\s*\)\s*,?/;

	# store value.
	$parms{$parm}{default} = $default;

	# try to search a comment on the previous line.
	if (!defined($parms{$parm}{desc})) {
	  if ($oldline =~ /^\s*\/\*\s*(.*)\s*\*\/\s*$/ || /\/\*\s*(.*)\s*\*\/\s*$/) {
	    $parms{$parm}{desc} = $1;
	  }
	}

	# try to search a comment on the line (multiline not supported).
	if (!defined($parms{$parm}{desc})) {
	  if ($descline =~ /^.*\/\*\s*(.*)\s*\*\/\s*$/) {
	    $parms{$parm}{desc} = $1;
	  }
	}
      }
    }
    $oldline = $_;
  }
  close F;

  # dump all result to stdout associated to current module.
  foreach $parm (keys %parms) {
    print "$module:$parm:$parms{$parm}{type}:$parms{$parm}{default}:$parms{$parm}{desc}\n";
  }
}

close FILE_LIST;