r12693: Move core data structures out of smb.h into core.h
[jelmer/samba4-debian.git] / source / build / smb_build / config_mk.pm
1 # Samba Build System
2 # - config.mk parsing functions
3 #
4 #  Copyright (C) Stefan (metze) Metzmacher 2004
5 #  Copyright (C) Jelmer Vernooij 2005
6 #  Released under the GNU GPL
7 #
8
9 package smb_build::config_mk;
10 use smb_build::input;
11 use File::Basename;
12
13 use strict;
14
15 my $section_types = {
16         "EXT_LIB" => {
17                 "LIBS"                  => "list",
18                 "CFLAGS"                => "list",
19                 "CPPFLAGS"              => "list",
20                 "LDFLAGS"               => "list",
21                 },
22         "SUBSYSTEM" => {
23                 "OBJ_FILES"             => "list",
24
25                 "REQUIRED_SUBSYSTEMS"   => "list",
26
27                 "ENABLE"                => "bool",
28                 "NOPROTO"               => "bool",
29
30                 "MANPAGE"               => "string",
31
32                 "PUBLIC_PROTO_HEADER"   => "string",
33                 "PRIVATE_PROTO_HEADER"  => "string",
34
35                 "PUBLIC_HEADERS"        => "list",
36                 },
37         "MODULE" => {
38                 "SUBSYSTEM"             => "string",
39
40                 "INIT_FUNCTION"         => "string",
41                 "OBJ_FILES"             => "list",
42
43                 "REQUIRED_SUBSYSTEMS"   => "list",
44
45                 "ENABLE"                => "bool",
46                 "NOPROTO"               => "bool",
47
48                 "OUTPUT_TYPE" => "string",
49
50                 "MANPAGE"               => "string",
51                 "PRIVATE_PROTO_HEADER"  => "string"
52                 },
53         "BINARY" => {
54                 "OBJ_FILES"             => "list",
55
56                 "REQUIRED_SUBSYSTEMS"   => "list",
57
58                 "ENABLE"                => "bool",
59                 "NOPROTO"               => "bool",
60
61                 "MANPAGE"               => "string",
62                 "INSTALLDIR"            => "string",
63                 "PRIVATE_PROTO_HEADER"  => "string",
64                 "PUBLIC_HEADERS" => "string"
65                 },
66         "LIBRARY" => {
67                 "MAJOR_VERSION"         => "string",
68                 "MINOR_VERSION"         => "string",
69                 "RELEASE_VERSION"       => "string",
70
71                 "OBJ_FILES"             => "list",
72
73                 "DESCRIPTION"           => "string",
74
75                 "REQUIRED_SUBSYSTEMS"   => "list",
76
77                 "ENABLE"                => "bool",
78                 "NOPROTO"               => "bool",
79
80                 "MANPAGE"               => "string",
81
82                 "PUBLIC_HEADERS"        => "list",
83
84                 "PUBLIC_PROTO_HEADER"   => "string",
85                 "PRIVATE_PROTO_HEADER"  => "string"
86                 }
87 };
88
89 use vars qw(@parsed_files);
90
91 @parsed_files = ();
92
93 ###########################################################
94 # The parsing function which parses the file
95 #
96 # $result = _parse_config_mk($filename)
97 #
98 # $filename -   the path of the config.mk file
99 #               which should be parsed
100 sub run_config_mk($$$)
101 {
102         sub run_config_mk($$$);
103         my ($input, $srcdir, $filename) = @_;
104         my $result;
105         my $linenum = -1;
106         my $infragment = 0;
107         my $section = "GLOBAL";
108         my $makefile = "";
109
110         push (@parsed_files, $srcdir."/".$filename);
111         
112         open(CONFIG_MK, $srcdir."/".$filename) or die("Can't open `$srcdir/$filename'\n");
113         my @lines = <CONFIG_MK>;
114         close(CONFIG_MK);
115
116         my $line = "";
117         my $prev = "";
118
119         foreach (@lines) {
120                 $linenum++;
121
122                 # lines beginning with '#' are ignored
123                 next if (/^\#.*$/);
124                 
125                 if (/^(.*)\\$/) {
126                         $prev .= $1;
127                         next;
128                 } else {
129                         $line = "$prev$_";
130                         $prev = "";
131                 }
132
133                 if ($line =~ /^\[([a-zA-Z0-9_:]+)\][\t ]*$/) 
134                 {
135                         $section = $1;
136                         $infragment = 0;
137                         next;
138                 }
139
140                 # include
141                 if ($line =~ /^include (.*)$/) {
142                         $makefile .= run_config_mk($input, $srcdir, dirname($filename)."/$1");
143                         next;
144                 }
145
146                 # empty line
147                 if ($line =~ /^[ \t]*$/) {
148                         $section = "GLOBAL";
149                         if ($infragment) { $makefile.="\n"; }
150                         next;
151                 }
152
153                 # global stuff is considered part of the makefile
154                 if ($section eq "GLOBAL") {
155                         $makefile .= $line;
156                         $infragment = 1;
157                         next;
158                 }
159
160                 
161                 # Assignment
162                 if ($line =~ /^([a-zA-Z0-9_]+)[\t ]*=(.*)$/) {
163                         $result->{$section}{$1}{VAL} = $2;
164                         $result->{$section}{$1}{KEY} = $1;
165                 
166                         next;
167                 }
168
169                 die("$srcdir."/".$filename:$linenum: Bad line while parsing $srcdir."/".$filename");
170         }
171
172         foreach my $section (keys %{$result}) {
173                 my ($type, $name) = split(/::/, $section, 2);
174
175                 my $sectype = $section_types->{$type};
176                 if (not defined($sectype)) {
177                         die($srcdir."/".$filename.":[".$section."] unknown section type \"".$type."\"!");
178                 }
179
180                 $input->{$name}{NAME} = $name;
181                 $input->{$name}{TYPE} = $type;
182                 $input->{$name}{BASEDIR} = dirname($filename);
183
184                 foreach my $key (values %{$result->{$section}}) {
185                         $key->{VAL} = smb_build::input::strtrim($key->{VAL});
186                         my $vartype = $sectype->{$key->{KEY}};
187                         if (not defined($vartype)) {
188                                 die($srcdir."/".$filename.":[".$section."]: unknown attribute type \"$key->{KEY}\"!");
189                         }
190                         if ($vartype eq "string") {
191                                 $input->{$name}{$key->{KEY}} = $key->{VAL};
192                         } elsif ($vartype eq "list") {
193                                 $input->{$name}{$key->{KEY}} = [smb_build::input::str2array($key->{VAL})];
194                         } elsif ($vartype eq "bool") {
195                                 if (($key->{VAL} ne "YES") and ($key->{VAL} ne "NO")) {
196                                         die("Invalid value for bool attribute $key->{KEY}: $key->{VAL} in section $section");
197                                 }
198                                 $input->{$name}{$key->{KEY}} = $key->{VAL};
199                         }
200                 }
201         }
202
203         return $makefile;
204 }
205
206 1;