r13786: [merge] Add registration functions for LDB modules
[sfrench/samba-autobuild/.git] / source4 / build / smb_build / config_mk.pm
index 517bca08ec993dd0ee91b6c8d5f9739ba6db66ea..c7ff8648ebe69ceebc553f528c3f693b7994faf6 100644 (file)
@@ -1,37 +1,96 @@
-###########################################################
-### SMB Build System                                   ###
-### - config.mk parsing functions                      ###
-###                                                    ###
-###  Copyright (C) Stefan (metze) Metzmacher 2004      ###
-###  Released under the GNU GPL                                ###
-###########################################################
+# Samba Build System
+# - config.mk parsing functions
+#
+#  Copyright (C) Stefan (metze) Metzmacher 2004
+#  Copyright (C) Jelmer Vernooij 2005
+#  Released under the GNU GPL
+#
 
-package config_mk;
+package smb_build::config_mk;
 use smb_build::input;
+use File::Basename;
 
 use strict;
 
-my %attribute_types = (
-       "NOPROTO" => "bool",
-       "REQUIRED_SUBSYSTEMS" => "list",
-       "OUTPUT_TYPE" => "string",
-       "INIT_OBJ_FILES" => "list",
-       "ADD_OBJ_FILES" => "list",
-       "OBJ_FILES" => "list",
-       "SUBSYSTEM" => "string",
-       "CFLAGS" => "list",
-       "CPPFLAGS" => "list",
-       "LDFLAGS" => "list",
-       "INSTALLDIR" => "string",
-       "LIBS" => "list",
-       "INIT_FUNCTION" => "string",
-       "MAJOR_VERSION" => "string",
-       "MINOR_VERSION" => "string",
-       "RELEASE_VERSION" => "string",
-       "ENABLE" => "bool",
-       "CMD" => "string",
-       "MANPAGE" => "string"
-);
+my $section_types = {
+       "EXT_LIB" => {
+               "LIBS"                  => "list",
+               "CFLAGS"                => "list",
+               "CPPFLAGS"              => "list",
+               "LDFLAGS"               => "list",
+               },
+       "SUBSYSTEM" => {
+               "OBJ_FILES"             => "list",
+
+               "REQUIRED_SUBSYSTEMS"   => "list",
+
+               "ENABLE"                => "bool",
+               "NOPROTO"               => "bool",
+
+               "MANPAGE"               => "string",
+
+               "PUBLIC_PROTO_HEADER"   => "string",
+               "PRIVATE_PROTO_HEADER"  => "string",
+
+               "PUBLIC_HEADERS"        => "list",
+               },
+       "MODULE" => {
+               "SUBSYSTEM"             => "string",
+
+               "INIT_FUNCTION"         => "string",
+               "OBJ_FILES"             => "list",
+
+               "REQUIRED_SUBSYSTEMS"   => "list",
+
+               "ENABLE"                => "bool",
+               "NOPROTO"               => "bool",
+
+               "OUTPUT_TYPE" => "string",
+
+               "MANPAGE"               => "string",
+               "PRIVATE_PROTO_HEADER"  => "string"
+               },
+       "BINARY" => {
+               "OBJ_FILES"             => "list",
+
+               "REQUIRED_SUBSYSTEMS"   => "list",
+
+               "ENABLE"                => "bool",
+               "NOPROTO"               => "bool",
+
+               "MANPAGE"               => "string",
+               "INSTALLDIR"            => "string",
+               "PRIVATE_PROTO_HEADER"  => "string",
+               "PUBLIC_HEADERS" => "string"
+               },
+       "LIBRARY" => {
+               "MAJOR_VERSION"         => "string",
+               "MINOR_VERSION"         => "string",
+               "RELEASE_VERSION"       => "string",
+               
+               "INIT_FUNCTION_TYPE" => "string",
+
+               "OBJ_FILES"             => "list",
+
+               "DESCRIPTION"           => "string",
+
+               "REQUIRED_SUBSYSTEMS"   => "list",
+
+               "ENABLE"                => "bool",
+               "NOPROTO"               => "bool",
+
+               "MANPAGE"               => "string",
+
+               "PUBLIC_HEADERS"        => "list",
+
+               "PUBLIC_PROTO_HEADER"   => "string",
+               "PRIVATE_PROTO_HEADER"  => "string"
+               }
+};
+
+use vars qw(@parsed_files);
+
+@parsed_files = ();
 
 ###########################################################
 # The parsing function which parses the file
@@ -40,143 +99,96 @@ my %attribute_types = (
 #
 # $filename -  the path of the config.mk file
 #              which should be parsed
-#
-# $result -    the resulting structure
-#
-# $result->{ERROR_CODE} -      the error_code, '0' means success
-# $result->{ERROR_STR} -       the error string
-#
-# $result->{$key}{KEY} -       the key == the variable which was parsed
-# $result->{$key}{VAL} -       the value of the variable
-sub _parse_config_mk($)
+sub run_config_mk($$$)
 {
-       my $filename = shift;
+       sub run_config_mk($$$);
+       my ($input, $srcdir, $filename) = @_;
        my $result;
        my $linenum = -1;
-       my $waiting = 0;
+       my $infragment = 0;
        my $section = "GLOBAL";
-       my $key;
-
-       $result->{ERROR_CODE} = -1;
+       my $makefile = "";
 
-       open(CONFIG_MK, "< $filename") || die ("Can't open $filename\n");
+       push (@parsed_files, $srcdir."/".$filename);
+       
+       open(CONFIG_MK, $srcdir."/".$filename) or die("Can't open `$srcdir/$filename'\n");
+       my @lines = <CONFIG_MK>;
+       close(CONFIG_MK);
 
-       while (<CONFIG_MK>) {
-               my $line = $_;
-               my $val;
+       my $line = "";
+       my $prev = "";
 
+       foreach (@lines) {
                $linenum++;
 
-               #
-               # lines beginnig with '#' are ignored
-               # 
-               if ($line =~ /^\#.*$/) {
+               # lines beginning with '#' are ignored
+               next if (/^\#.*$/);
+               
+               if (/^(.*)\\$/) {
+                       $prev .= $1;
                        next;
+               } else {
+                       $line = "$prev$_";
+                       $prev = "";
                }
 
-               #
-               #
-               #
-               if (($waiting == 0) && ($line =~ /^\[([a-zA-Z0-9_:]+)\][\t ]*$/)) {
+               if ($line =~ /^\[([a-zA-Z0-9_:]+)\][\t ]*$/) 
+               {
                        $section = $1;
+                       $infragment = 0;
                        next;
                }
-               
-               #
-               # 1.)   lines with an alphanumeric character indicate
-               #       a new variable, 
-               # 2.)   followed by zero or more whitespaces or tabs
-               # 3.)   then one '=' character
-               # 4.)   followed by the value of the variable
-               # 5.)   a newline ('\n') can be escaped by a '\' before the newline
-               #       and the next line needs to start with a tab ('\t')
-               #
-               if (($waiting == 0) && ($line =~ /^([a-zA-Z0-9_]+)[\t ]*=(.*)$/)) {
-                       $key = $1;
-                       $val = $2;
-
-                       #
-                       # when we have a '\' before the newline 
-                       # then skip it and wait for the next line.
-                       #
-                       if ($val =~ /(.*)(\\)$/) {
-                               $val = $1;
-                               $waiting = 1;           
-                       } else {
-                               $waiting = 0;
-                       }
 
-                       $result->{$section}{$key}{KEY} = $key;
-                       $result->{$section}{$key}{VAL} = $val;
+               # include
+               if ($line =~ /^include (.*)$/) {
+                       $makefile .= run_config_mk($input, $srcdir, dirname($filename)."/$1");
                        next;
                }
 
-               #
-               # when we are waiting for a value to continue then
-               # check if it has a leading tab.
-               #
-               if (($waiting == 1) && ($line =~ /^\t(.*)$/)) {
-                       $val = $1;
-
-                       #
-                       # when we have a '\' before the newline 
-                       # then skip it and wait for the next line.
-                       #
-                       if ($val =~ /(.*)( \\)$/) {
-                               $val = $1;
-                               $waiting = 1;           
-                       } else {
-                               $waiting = 0;
-                       }
-
-                       $result->{$section}{$key}{VAL} .= " ";
-                       $result->{$section}{$key}{VAL} .= $val;
+               # empty line
+               if ($line =~ /^[ \t]*$/) {
+                       $section = "GLOBAL";
+                       if ($infragment) { $makefile.="\n"; }
                        next;
                }
 
-               #
-               # catch empty lines they're ignored
-               # and we're no longer waiting for the value to continue
-               #
-               if ($line =~ /^$/) {
-                       $waiting = 0;
+               # global stuff is considered part of the makefile
+               if ($section eq "GLOBAL") {
+                       if (!$infragment) { $makefile.="\n"; }
+                       $makefile .= $line;
+                       $infragment = 1;
                        next;
                }
 
-               close(CONFIG_MK);
-
-               $result->{ERROR_STR} = "Bad line while parsing $filename\n$filename:$linenum: $line";
+               
+               # Assignment
+               if ($line =~ /^([a-zA-Z0-9_]+)[\t ]*=(.*)$/) {
+                       $result->{$section}{$1}{VAL} = $2;
+                       $result->{$section}{$1}{KEY} = $1;
+               
+                       next;
+               }
 
-               return $result;
+               die("$srcdir."/".$filename:$linenum: Bad line while parsing $srcdir."/".$filename");
        }
 
-       close(CONFIG_MK);
-
-       $result->{ERROR_CODE} = 0;
-
-       return $result;
-}
-
-sub import_file($$)
-{
-       my ($input, $filename) = @_;
-
-       my $result = _parse_config_mk($filename);
-
-       die ($result->{ERROR_STR}) unless $result->{ERROR_CODE} == 0;
-
        foreach my $section (keys %{$result}) {
-               next if ($section eq "ERROR_CODE");
                my ($type, $name) = split(/::/, $section, 2);
-               
+
+               my $sectype = $section_types->{$type};
+               if (not defined($sectype)) {
+                       die($srcdir."/".$filename.":[".$section."] unknown section type \"".$type."\"!");
+               }
+
                $input->{$name}{NAME} = $name;
                $input->{$name}{TYPE} = $type;
+               $input->{$name}{BASEDIR} = dirname($filename);
 
                foreach my $key (values %{$result->{$section}}) {
                        $key->{VAL} = smb_build::input::strtrim($key->{VAL});
-                       my $vartype = $attribute_types{$key->{KEY}};
+                       my $vartype = $sectype->{$key->{KEY}};
                        if (not defined($vartype)) {
-                               die("Unknown attribute $key->{KEY}");
+                               die($srcdir."/".$filename.":[".$section."]: unknown attribute type \"$key->{KEY}\"!");
                        }
                        if ($vartype eq "string") {
                                $input->{$name}{$key->{KEY}} = $key->{VAL};
@@ -184,27 +196,14 @@ sub import_file($$)
                                $input->{$name}{$key->{KEY}} = [smb_build::input::str2array($key->{VAL})];
                        } elsif ($vartype eq "bool") {
                                if (($key->{VAL} ne "YES") and ($key->{VAL} ne "NO")) {
-                                       die("Invalid value for bool attribute $key->{KEY}: $key->{VAL}");
+                                       die("Invalid value for bool attribute $key->{KEY}: $key->{VAL} in section $section");
                                }
                                $input->{$name}{$key->{KEY}} = $key->{VAL};
                        }
                }
        }
-}
-
-sub import_files($$)
-{
-       my ($input, $config_list) = @_;
-
-       open(IN, $config_list) or die("Can't open $config_list: $!");
-       my @mkfiles = grep{!/^#/} <IN>;
-       close(IN);
 
-       $| = 1;
-
-       foreach (@mkfiles) {
-               s/\n//g;
-               import_file($input, $_);
-       }
+       return $makefile;
 }
+
 1;