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