lib/param: generate the param_functions.h containing the prototypes
[samba.git] / source4 / script / mkproto.pl
index ea2e5acd45f485be53d870dd851c0d4030d1b710..2c3ebac0f99275a9e3b78e374e57d56f85a2c717 100755 (executable)
@@ -17,14 +17,15 @@ use File::Path;
 
 my $public_file = undef;
 my $private_file = undef;
+my $all_file = undef;
 my $public_define = undef;
 my $private_define = undef;
 my $_public = "";
 my $_private = "";
 my $public_data = \$_public;
 my $private_data = \$_private;
-my $builddir = undef;
-my $srcdir = undef;
+my $builddir = ".";
+my $srcdir = ".";
 
 sub public($)
 {
@@ -55,6 +56,7 @@ sub usage()
 
 GetOptions(
        'public=s' => sub { my ($f,$v) = @_; $public_file = $v; },
+       'all=s' => sub { my ($f,$v) = @_; $public_file = $v; $private_file = $v; },
        'private=s' => sub { my ($f,$v) = @_; $private_file = $v; },
        'define=s' => sub { 
                my ($f,$v) = @_; 
@@ -68,20 +70,24 @@ GetOptions(
        'help' => \&usage
 ) or exit(1);
 
-if (not defined($public_define) and defined($public_file)) {
-       $public_define = ".." . uc($public_file) . "__";
-       $public_define =~ tr{./}{__};
-} elsif (not defined($public_define)) {
-       $public_define = '_PROTO_H_';
-}
+sub normalize_define($$)
+{
+       my ($define, $file) = @_;
+
+       if (not defined($define) and defined($file)) {
+               $define = "__" . uc($file) . "__";
+               $define =~ tr{./}{__};
+               $define =~ tr{\-}{_};
+       } elsif (not defined($define)) {
+               $define = '_PROTO_H_';
+       }
 
-if (not defined($private_define) and defined($private_file)) {
-       $private_define = "__" . uc($private_file) . "__";
-       $private_define =~ tr{./}{__};
-} elsif (not defined($public_define)) {
-       $public_define = '_PROTO_H_';
+       return $define;
 }
 
+$public_define = normalize_define($public_define, $public_file);
+$private_define = normalize_define($private_define, $private_file);
+
 if ((defined($private_file) and defined($public_file) and ($private_file eq $public_file)) or 
        (not defined($private_file) and not defined($public_file))) {
        $private_data = $public_data;
@@ -89,9 +95,9 @@ if ((defined($private_file) and defined($public_file) and ($private_file eq $pub
 
 sub file_load($)
 {
-    my($filename) = shift;
+    my($filename) = @_;
     local(*INPUTFILE);
-    open(INPUTFILE, $filename) || return undef;
+    open(INPUTFILE, $filename) or return undef;
     my($saved_delim) = $/;
     undef $/;
     my($data) = <INPUTFILE>;
@@ -118,50 +124,38 @@ sub print_footer($$)
        $file->("\n#endif /* $header_name */\n\n");
 }
 
-sub handle_loadparm($$) 
-{
-       my ($file,$line) = @_;
-
-       if ($line =~ /^_PUBLIC_ FN_(GLOBAL|LOCAL)_(CONST_STRING|STRING|BOOL|bool|CHAR|INTEGER|LIST)\((\w+),.*\)/o) {
-               my $scope = $1;
-               my $type = $2;
-               my $name = $3;
-
-               my %tmap = (
-                           "BOOL" => "BOOL ",
-                               "bool" => "bool ",
-                           "CONST_STRING" => "const char *",
-                           "STRING" => "const char *",
-                           "INTEGER" => "int ",
-                           "CHAR" => "char ",
-                           "LIST" => "const char **",
-                           );
-
-               my %smap = (
-                           "GLOBAL" => "void",
-                           "LOCAL" => "int "
-                           );
-
-               $file->("$tmap{$type}$name($smap{$scope});\n");
-       }
-}
-
 sub process_file($$$) 
 {
        my ($public_file, $private_file, $filename) = @_;
 
        $filename =~ s/\.o$/\.c/g;
 
-       if (!open(FH, "< $builddir/$filename")) {
+       if ($filename =~ /^\//) {
+               open(FH, "<$filename") or die("Failed to open $filename");
+       } elsif (!open(FH, "< $builddir/$filename")) {
            open(FH, "< $srcdir/$filename") || die "Failed to open $filename";
        }
 
        $private_file->("\n/* The following definitions come from $filename  */\n\n");
 
+       my $comment = undef;
+       my $incomment = 0;
        while (my $line = <FH>) {             
                my $target = \&private;
                my $is_public = 0;
 
+               if ($line =~ /^\/\*\*/) { 
+                       $comment = "";
+                       $incomment = 1;
+               }
+
+               if ($incomment) {
+                       $comment .= $line;
+                       if ($line =~ /\*\//) {
+                               $incomment = 0;
+                       }
+               } 
+
                # these are ordered for maximum speed
                next if ($line =~ /^\s/);
              
@@ -169,8 +163,7 @@ sub process_file($$$)
 
                next if ($line =~ /^\/|[;]/);
 
-               if ($line =~ /^_PUBLIC_ FN_/) {
-                       handle_loadparm($public_file, $line);
+               if ($line =~ /^FN_/) {
                        next;
                }
 
@@ -180,14 +173,17 @@ sub process_file($$$)
                }
 
                next unless ( $is_public || $line =~ /
-                             ^void|^BOOL|^bool|^int|^struct|^char|^const|^\w+_[tT]\s|^uint|^unsigned|^long|
-                             ^NTSTATUS|^ADS_STATUS|^enum\s.*\(|^DATA_BLOB|^WERROR|^XFILE|^FILE|^DIR|
-                             ^double|^TDB_CONTEXT|^TDB_DATA|^TALLOC_CTX|^NTTIME|^FN_|^init_module|
-                             ^GtkWidget|^GType|^smb_ucs2_t|^krb5_error_code
+                             ^(_DEPRECATED_ |_NORETURN_ |_WARN_UNUSED_RESULT_ |_PURE_ )*(
+                                 void|bool|int|struct|char|const|\w+_[tT]\s|uint|unsigned|long|NTSTATUS|
+                                 ADS_STATUS|enum\s.*\(|DATA_BLOB|WERROR|XFILE|FILE|DIR|
+                             double|TDB_CONTEXT|TDB_DATA|TALLOC_CTX|NTTIME|FN_|init_module|
+                             GtkWidget|GType|smb_ucs2_t|krb5_error_code|NET_API_STATUS)
                              /xo);
 
                next if ($line =~ /^int\s*main/);
 
+               $target->("\n$comment") if (defined($comment)); $comment = undef;
+
                if ( $line =~ /\(.*\)\s*$/o ) {
                        chomp $line;
                        $target->("$line;\n");
@@ -211,7 +207,7 @@ sub process_file($$$)
 
 
 print_header(\&public, $public_define);
-if ($public_file ne $private_file) {
+if (defined($private_file) and defined($public_file) and $public_file ne $private_file) {
        print_header(\&private, $private_define);
 
        private("/* this file contains prototypes for functions that " .
@@ -224,10 +220,14 @@ if ($public_file ne $private_file) {
 }
 
 public("#ifndef _PUBLIC_\n#define _PUBLIC_\n#endif\n\n");
+public("#ifndef _PURE_\n#define _PURE_\n#endif\n\n");
+public("#ifndef _NORETURN_\n#define _NORETURN_\n#endif\n\n");
+public("#ifndef _DEPRECATED_\n#define _DEPRECATED_\n#endif\n\n");
+public("#ifndef _WARN_UNUSED_RESULT_\n#define _WARN_UNUSED_RESULT_\n#endif\n\n");
 
 process_file(\&public, \&private, $_) foreach (@ARGV);
 print_footer(\&public, $public_define);
-if ($public_file ne $private_file) {
+if (defined($private_file) and $public_file ne $private_file) {
        print_footer(\&private, $private_define);
 }
 
@@ -239,15 +239,12 @@ if (not defined($private_file) and defined($public_file)) {
        print STDOUT $$private_data;
 }
 
-my $old_public_data = file_load($public_file);
-my $old_private_data = file_load($private_file);
-
 mkpath(dirname($public_file), 0, 0755);
 open(PUBLIC, ">$public_file") or die("Can't open `$public_file': $!"); 
 print PUBLIC "$$public_data";
 close(PUBLIC);
 
-if ($public_file ne $private_file) {
+if (defined($private_file) and $public_file ne $private_file) {
        mkpath(dirname($private_file), 0, 0755);
        open(PRIVATE, ">$private_file") or die("Can't open `$private_file': $!"); 
        print PRIVATE "$$private_data";