r3733: More build system fixes/features:
[gd/samba/.git] / source4 / build / smb_build / config_mk.pm
1 ###########################################################
2 ### SMB Build System                                    ###
3 ### - config.mk parsing functions                       ###
4 ###                                                     ###
5 ###  Copyright (C) Stefan (metze) Metzmacher 2004       ###
6 ###  Released under the GNU GPL                         ###
7 ###########################################################
8
9 package config_mk;
10 use input;
11
12 use strict;
13
14 ###########################################################
15 # The parsing function which parses the file
16 #
17 # $result = _parse_config_mk($filename)
18 #
19 # $filename -   the path of the config.mk file
20 #               which should be parsed
21 #
22 # $result -     the resulting structure
23 #
24 # $result->{ERROR_CODE} -       the error_code, '0' means success
25 # $result->{ERROR_STR} -        the error string
26 #
27 # $result->{$key}{KEY} -        the key == the variable which was parsed
28 # $result->{$key}{VAL} -        the value of the variable
29 sub _parse_config_mk($)
30 {
31         my $filename = shift;
32         my $result;
33         my $linenum = -1;
34         my $waiting = 0;
35         my $section = "GLOBAL";
36         my $key;
37
38         $result->{ERROR_CODE} = -1;
39
40         open(CONFIG_MK, "< $filename") || die ("Can't open $filename\n");
41
42         while (<CONFIG_MK>) {
43                 my $line = $_;
44                 my $val;
45
46                 $linenum++;
47
48                 #
49                 # lines beginnig with '#' are ignored
50                 # 
51                 if ($line =~ /^\#.*$/) {
52                         next;
53                 }
54
55                 #
56                 #
57                 #
58                 if (($waiting == 0) && ($line =~ /^\[([a-zA-Z0-9_:]+)\][\t ]*$/)) {
59                         $section = $1;
60                         next;
61                 }
62                 
63                 #
64                 # 1.)   lines with an alphanumeric character indicate
65                 #       a new variable, 
66                 # 2.)   followed by zero or more whitespaces or tabs
67                 # 3.)   then one '=' character
68                 # 4.)   followed by the value of the variable
69                 # 5.)   a newline ('\n') can be escaped by a '\' before the newline
70                 #       and the next line needs to start with a tab ('\t')
71                 #
72                 if (($waiting == 0) && ($line =~ /^([a-zA-Z0-9_]+)[\t ]*=(.*)$/)) {
73                         $key = $1;
74                         $val = $2;
75
76                         #
77                         # when we have a '\' before the newline 
78                         # then skip it and wait for the next line.
79                         #
80                         if ($val =~ /(.*)(\\)$/) {
81                                 $val = $1;
82                                 $waiting = 1;           
83                         } else {
84                                 $waiting = 0;
85                         }
86
87                         $result->{$section}{$key}{KEY} = $key;
88                         $result->{$section}{$key}{VAL} = $val;
89                         next;
90                 }
91
92                 #
93                 # when we are waiting for a value to continue then
94                 # check if it has a leading tab.
95                 #
96                 if (($waiting == 1) && ($line =~ /^\t(.*)$/)) {
97                         $val = $1;
98
99                         #
100                         # when we have a '\' before the newline 
101                         # then skip it and wait for the next line.
102                         #
103                         if ($val =~ /(.*)( \\)$/) {
104                                 $val = $1;
105                                 $waiting = 1;           
106                         } else {
107                                 $waiting = 0;
108                         }
109
110                         $result->{$section}{$key}{VAL} .= " ";
111                         $result->{$section}{$key}{VAL} .= $val;
112                         next;
113                 }
114
115                 #
116                 # catch empty lines they're ignored
117                 # and we're no longer waiting for the value to continue
118                 #
119                 if ($line =~ /^$/) {
120                         $waiting = 0;
121                         next;
122                 }
123
124                 close(CONFIG_MK);
125
126                 $result->{ERROR_STR} = "Bad line while parsing $filename\n$filename:$linenum: $line";
127
128                 return $result;
129         }
130
131         close(CONFIG_MK);
132
133         $result->{ERROR_CODE} = 0;
134
135         return $result;
136 }
137
138 ###########################################################
139 # A caching function to avoid to parse
140 # a file twice or more
141 #
142 # $result = _get_parse_results($filename)
143 #
144 # $filename -   the path of the config.mk file
145 #               which should be parsed
146 #
147 # $result -     the resulting structure
148 #
149 # $result->{ERROR_CODE} -       the error_code, '0' means success
150 # $result->{ERROR_STR} -        the error string
151 #
152 # $result->{$key}{KEY} -        the key == the variable which was parsed
153 # $result->{$key}{VAL} -        the value of the variable
154 my $_get_parse_results_cache;
155 sub _get_parse_results($)
156 {
157         my $filename = shift;
158
159         if ((!defined($_get_parse_results_cache->{$filename}{ERROR_CODE}))
160                 ||($_get_parse_results_cache->{$filename}{ERROR_CODE} != 0)) {
161                 $_get_parse_results_cache->{$filename} = _parse_config_mk($filename);
162         }
163
164         return $_get_parse_results_cache->{$filename};
165 }
166
167 ###########################################################
168 # The fetching function to fetch the value of a variable 
169 # out of the file
170 #
171 # $value = _fetch_var_from_config_mk($filename,$section,$variable)
172 #
173 # $filename -   the path of the config.mk file
174 #               which should be parsed
175 #
176 # $section  -   the section name of the variable
177 #
178 # $variable -   the variable name of which we want the value
179 #
180 # $value -      the value of the variable
181 sub _fetch_var_from_config_mk($$$)
182 {
183         my $filename = shift;
184         my $section = shift;
185         my $key = shift;
186         my $val = "";
187         my $result;
188
189         $result = _get_parse_results($filename);
190
191         if ($result->{ERROR_CODE} != 0) {
192                 die ($result->{ERROR_STR});
193         }
194
195         if (defined($result->{$section}{$key})) {
196                 $val = input::strtrim($result->{$section}{$key}{VAL});
197         } elsif (defined($result->{DEFAULT}{$key})) {
198                 $val = input::strtrim($result->{DEFAULT}{$key}{VAL});
199         }
200
201         return $val;
202 }
203
204 ###########################################################
205 # The fetching function to fetch the array of values of a variable 
206 # out of the file
207 #
208 # $array = _fetch_array_from_config_mk($filename,$section,$variable)
209 #
210 # $filename -   the path of the config.mk file
211 #               which should be parsed
212 #
213 # $section  -   the section name of the variable
214 #
215 # $variable -   the variable name of which we want the value
216 #
217 # $array -      the array of values of the variable
218 sub _fetch_array_from_config_mk($$$)
219 {
220         my $filename = shift;
221         my $section = shift;
222         my $key = shift;
223         my $result;
224         my $val = "";
225
226         $result = _get_parse_results($filename);
227
228         if ($result->{ERROR_CODE} != 0) {
229                 die ($result->{ERROR_STR});
230         }
231
232         if (defined($result->{$section}{$key})) {
233                 $val = $result->{$section}{$key}{VAL};
234         } elsif (defined($result->{DEFAULT}{$key})) {
235                 $val = $result->{DEFAULT}{$key}{VAL};
236         } 
237
238         return input::str2array($val);
239 }
240
241 ###########################################################
242 # A function for fetching MODULE_<module>_<parameter>
243 # variables out of a config.mk file
244 #
245 # $value = module_get_var($filename,$module,$parameter)
246 #
247 # $filename -   the path of the config.mk file
248 #               which should be parsed
249 #
250 # $module -     the middle part of the variable name of which we want the value
251 #
252 # $parameter -  the last part of the variable name of which we want the value
253 #
254 # $value -      the value of the variable
255 sub module_get_var($$$)
256 {
257         my $filename = shift;
258         my $module = shift;
259         my $var = shift;
260
261         my $section = "MODULE::".$module;
262
263         return _fetch_var_from_config_mk($filename,$section,$var);
264 }
265
266 ###########################################################
267 # A function for fetching MODULE_<module>_<parameter>
268 # variables out of a config.mk file
269 #
270 # $array = module_get_array($filename,$module,$parameter)
271 #
272 # $filename -   the path of the config.mk file
273 #               which should be parsed
274 #
275 # $module -     the middle part of the variable name of which we want the value
276 #
277 # $parameter -  the last part of the variable name of which we want the value
278 #
279 # $array -      the array of values of the variable
280 sub module_get_array($$$)
281 {
282         my $filename = shift;
283         my $module = shift;
284         my $var = shift;
285
286         my $section = "MODULE::".$module;
287
288         return _fetch_array_from_config_mk($filename,$section,$var);
289 }
290
291 ###########################################################
292 # A function for fetching SUBSYSTEM_<subsystem>_<parameter>
293 # variables out of a config.mk file
294 #
295 # $value = subsystem_get_var($filename,$subsystem,$parameter)
296 #
297 # $filename -   the path of the config.mk file
298 #               which should be parsed
299 #
300 # $subsystem -  the middle part of the variable name of which we want the value
301 #
302 # $parameter -  the last part of the variable name of which we want the value
303 #
304 # $value -      the value of the variable
305 sub subsystem_get_var($$$)
306 {
307         my $filename = shift;
308         my $subsystem = shift;
309         my $var = shift;
310
311         my $section = "SUBSYSTEM::".$subsystem;
312
313         return _fetch_var_from_config_mk($filename,$section,$var);
314 }
315
316 ###########################################################
317 # A function for fetching SUBSYSTEM_<subsystem>_<parameter>
318 # variables out of a config.mk file
319 #
320 # $array = subsystem_get_array($filename,$subsystem,$parameter)
321 #
322 # $filename -   the path of the config.mk file
323 #               which should be parsed
324 #
325 # $subsystem -  the middle part of the variable name of which we want the value
326 #
327 # $parameter -  the last part of the variable name of which we want the value
328 #
329 # $array -      the array of values of the variable
330 sub subsystem_get_array($$$)
331 {
332         my $filename = shift;
333         my $subsystem = shift;
334         my $var = shift;
335
336         my $section = "SUBSYSTEM::".$subsystem;
337
338         return _fetch_array_from_config_mk($filename,$section,$var);
339 }
340
341 ###########################################################
342 # A function for fetching LIBRARY_<library>_<parameter>
343 # variables out of a config.mk file
344 #
345 # $value = library_get_var($filename,$library,$parameter)
346 #
347 # $filename -   the path of the config.mk file
348 #               which should be parsed
349 #
350 # $library -    the middle part of the variable name of which we want the value
351 #
352 # $parameter -  the last part of the variable name of which we want the value
353 #
354 # $value -      the value of the variable
355 sub library_get_var($$$)
356 {
357         my $filename = shift;
358         my $library = shift;
359         my $var = shift;
360
361         my $section = "LIBRARY::".$library;
362
363         return _fetch_var_from_config_mk($filename,$section,$var);
364 }
365
366 ###########################################################
367 # A function for fetching LIBRARY_<library>_<parameter>
368 # variables out of a config.mk file
369 #
370 # $array = library_get_array($filename,$library,$parameter)
371 #
372 # $filename -   the path of the config.mk file
373 #               which should be parsed
374 #
375 # $library -    the middle part of the variable name of which we want the value
376 #
377 # $parameter -  the last part of the variable name of which we want the value
378 #
379 # $array -      the array of values of the variable
380 sub library_get_array($$$)
381 {
382         my $filename = shift;
383         my $library = shift;
384         my $var = shift;
385
386         my $section = "LIBRARY::".$library;
387
388         return _fetch_array_from_config_mk($filename,$section,$var);
389 }
390
391 ###########################################################
392 # A function for fetching BINARY_<binary>_<parameter>
393 # variables out of a config.mk file
394 #
395 # $value = binary_get_var($filename,$binary,$parameter)
396 #
397 # $filename -   the path of the config.mk file
398 #               which should be parsed
399 #
400 # $binary -     the middle part of the variable name of which we want the value
401 #
402 # $parameter -  the last part of the variable name of which we want the value
403 #
404 # $value -      the value of the variable
405 sub binary_get_var($$$)
406 {
407         my $filename = shift;
408         my $binary = shift;
409         my $var = shift;
410
411         my $section = "BINARY::".$binary;
412
413         return _fetch_var_from_config_mk($filename,$section,$var);
414 }
415
416 ###########################################################
417 # A function for fetching BINARY_<binary>_<parameter>
418 # variables out of a config.mk file
419 #
420 # $array = binary_get_array($filename,$binary,$parameter)
421 #
422 # $filename -   the path of the config.mk file
423 #               which should be parsed
424 #
425 # $binary -     the middle part of the variable name of which we want the value
426 #
427 # $parameter -  the last part of the variable name of which we want the value
428 #
429 # $array -      the array of values of the variable
430 sub binary_get_array($$$)
431 {
432         my $filename = shift;
433         my $binary = shift;
434         my $var = shift;
435
436         my $section = "BINARY::".$binary;
437
438         return _fetch_array_from_config_mk($filename,$section,$var);
439 }
440
441 sub import_file($$)
442 {
443         my $input = shift;
444         my $filename = shift;
445
446         my $result = _parse_config_mk($filename);
447
448         die ($result->{ERROR_STR}) unless $result->{ERROR_CODE} == 0;
449
450         foreach my $section (keys %{$result}) {
451                 next if ($section eq "ERROR_CODE");
452                 my ($type, $name) = split(/::/, $section, 2);
453                 
454                 $input->{$name}{NAME} = $name;
455                 $input->{$name}{TYPE} = $type;
456
457                 foreach my $key (values %{$result->{$section}}) {
458                         $input->{$name}{$key->{KEY}} = [input::str2array($key->{VAL})];
459                 }
460         }
461 }
462 1;