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