r18293: use the correct name it's not always under $srcdir...
[metze/samba/wip.git] / source4 / 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                 "PRIVATE_DEPENDENCIES"  => "list",
26                 "PUBLIC_DEPENDENCIES"   => "list",
27
28                 "ENABLE"                => "bool",
29
30                 "MANPAGE"               => "string",
31
32                 "PUBLIC_PROTO_HEADER"   => "string",
33                 "PRIVATE_PROTO_HEADER"  => "string",
34
35                 "PUBLIC_HEADERS"        => "list",
36
37                 "CFLAGS"                => "list",
38                 "LDFLAGS"               => "list",
39                 "STANDARD_VISIBILITY"   => "string"
40                 },
41         "MODULE" => {
42                 "SUBSYSTEM"             => "string",
43
44                 "INIT_FUNCTION"         => "string",
45                 "OBJ_FILES"             => "list",
46
47                 "PUBLIC_DEPENDENCIES"   => "list",
48                 "PRIVATE_DEPENDENCIES"  => "list",
49
50                 "ALIASES" => "list",
51
52                 "ENABLE"                => "bool",
53
54                 "OUTPUT_TYPE"           => "string",
55
56                 "MANPAGE"               => "string",
57                 "PRIVATE_PROTO_HEADER"  => "string",
58                 "PUBLIC_PROTO_HEADER"   => "string",
59
60
61                 "PUBLIC_HEADERS"        => "list",
62
63                 "CFLAGS"                => "list"
64                 },
65         "BINARY" => {
66                 "OBJ_FILES"             => "list",
67
68                 "PRIVATE_DEPENDENCIES"  => "list",
69
70                 "ENABLE"                => "bool",
71
72                 "MANPAGE"               => "string",
73                 "INSTALLDIR"            => "string",
74                 "PRIVATE_PROTO_HEADER"  => "string",
75                 "PUBLIC_PROTO_HEADER"   => "string",
76                 "PUBLIC_HEADERS"        => "list", 
77
78                 "CFLAGS"                => "list",
79                 "STANDARD_VISIBILITY"   => "string",
80
81                 "USE_HOSTCC"            => "bool"
82                 },
83         "LIBRARY" => {
84                 "VERSION"               => "string",
85                 "SO_VERSION"            => "string",
86                 "LIBRARY_REALNAME" => "string",
87                 
88                 "INIT_FUNCTION_TYPE"    => "string",
89
90                 "OBJ_FILES"             => "list",
91
92                 "DESCRIPTION"           => "string",
93
94                 "PRIVATE_DEPENDENCIES"  => "list",
95                 "PUBLIC_DEPENDENCIES"   => "list",
96
97                 "ENABLE"                => "bool",
98
99                 "MANPAGE"               => "string",
100
101                 "PUBLIC_HEADERS"        => "list",
102
103                 "PUBLIC_PROTO_HEADER"   => "string",
104                 "PRIVATE_PROTO_HEADER"  => "string",
105
106                 "CFLAGS"                => "list",
107                 "LDFLAGS"               => "list",
108                 "STANDARD_VISIBILITY"   => "string"
109                 }
110 };
111
112 use vars qw(@parsed_files);
113
114 @parsed_files = ();
115
116 ###########################################################
117 # The parsing function which parses the file
118 #
119 # $result = _parse_config_mk($filename)
120 #
121 # $filename -   the path of the config.mk file
122 #               which should be parsed
123 sub run_config_mk($$$$)
124 {
125         sub run_config_mk($$$$);
126         my ($input, $srcdir, $builddir, $filename) = @_;
127         my $result;
128         my $linenum = -1;
129         my $infragment = 0;
130         my $section = "GLOBAL";
131         my $makefile = "";
132
133         my $parsing_file = $builddir."/".$filename;
134
135         $ENV{samba_builddir} = $builddir;
136         $ENV{samba_srcdir} = $srcdir;
137         
138         if (!open(CONFIG_MK, $parsing_file)) { 
139                 $parsing_file = $srcdir."/".$filename;
140                 open(CONFIG_MK, $parsing_file) or 
141                     die("Can't open neither `$builddir."/".$filename' nor `$srcdir/$filename'\n");
142         }
143         
144         push (@parsed_files, $parsing_file);
145         
146         
147         my @lines = <CONFIG_MK>;
148         close(CONFIG_MK);
149
150         my $line = "";
151         my $prev = "";
152
153         foreach (@lines) {
154                 $linenum++;
155
156                 # lines beginning with '#' are ignored
157                 next if (/^\#.*$/);
158                 
159                 if (/^(.*)\\$/) {
160                         $prev .= $1;
161                         next;
162                 } else {
163                         $line = "$prev$_";
164                         $prev = "";
165                 }
166
167                 if ($line =~ /^\[([-a-zA-Z0-9_:]+)\][\t ]*$/) 
168                 {
169                         $section = $1;
170                         $infragment = 0;
171                         next;
172                 }
173
174                 # include
175                 if ($line =~ /^include (.*)$/) {
176                         $makefile .= run_config_mk($input, $srcdir, $builddir, dirname($filename)."/$1");
177                         next;
178                 }
179
180                 # empty line
181                 if ($line =~ /^[ \t]*$/) {
182                         $section = "GLOBAL";
183                         if ($infragment) { $makefile.="\n"; }
184                         next;
185                 }
186
187                 # global stuff is considered part of the makefile
188                 if ($section eq "GLOBAL") {
189                         if (!$infragment) { $makefile.="\n"; }
190                         $makefile .= $line;
191                         $infragment = 1;
192                         next;
193                 }
194
195                 
196                 # Assignment
197                 if ($line =~ /^([a-zA-Z0-9_]+)[\t ]*=(.*)$/) {
198                         $result->{$section}{$1}{VAL} = $2;
199                         $result->{$section}{$1}{KEY} = $1;
200                 
201                         next;
202                 }
203
204                 die("$parsing_file:$linenum: Bad line while parsing $parsing_file");
205         }
206
207         foreach my $section (keys %{$result}) {
208                 my ($type, $name) = split(/::/, $section, 2);
209
210                 my $sectype = $section_types->{$type};
211                 if (not defined($sectype)) {
212                         die($parsing_file.":[".$section."] unknown section type \"".$type."\"!");
213                 }
214
215                 $input->{$name}{NAME} = $name;
216                 $input->{$name}{TYPE} = $type;
217                 $input->{$name}{MK_FILE} = $parsing_file;
218                 $input->{$name}{BASEDIR} = dirname($filename);
219
220                 foreach my $key (values %{$result->{$section}}) {
221                         $key->{VAL} = smb_build::input::strtrim($key->{VAL});
222                         my $vartype = $sectype->{$key->{KEY}};
223                         if (not defined($vartype)) {
224                                 die($parsing_file.":[".$section."]: unknown attribute type \"$key->{KEY}\"!");
225                         }
226                         if ($vartype eq "string") {
227                                 $input->{$name}{$key->{KEY}} = $key->{VAL};
228                         } elsif ($vartype eq "list") {
229                                 $input->{$name}{$key->{KEY}} = [smb_build::input::str2array($key->{VAL})];
230                         } elsif ($vartype eq "bool") {
231                                 if (($key->{VAL} ne "YES") and ($key->{VAL} ne "NO")) {
232                                         die("Invalid value for bool attribute $key->{KEY}: $key->{VAL} in section $section");
233                                 }
234                                 $input->{$name}{$key->{KEY}} = $key->{VAL};
235                         }
236                 }
237         }
238
239         return $makefile;
240 }
241
242 1;