help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

complex gmake conditionals: NOT ( ifndef(arg1) AND ifdef(arg2) )


From: Alexander.Farber
Subject: complex gmake conditionals: NOT ( ifndef(arg1) AND ifdef(arg2) )
Date: Wed, 19 May 2004 11:40:54 +0200

Hi,

I'm trying to convert some weird build system, consisting
of many files, containing C-preprocessor statements, into 
GNU makefiles. I'm able to parse the input files using perl 
(the script is attached), but for some #if/#endif constructs 
I'm unable to find the GNU make counterparts, because gmake 
doesn't provide logical operators like NOT, OR, AND. 

For example those two are easy to convert:

        #if ! defined val1
        key1 val2
        #endif

        #if ( (defined ( val3 ) ) || ( ! defined (val4) ) )
        key2 val5
        #endif

they become:

        ifndef(val1)
                key1 = val2
        endif

        ifndef(val3)
                ifdef(val4)
                        key2 = val5
                endif
        endif

But what do I do with something like

        #if ! ( (defined ( val3 ) ) || ( ! defined (val4) ) )
        key2 val5
        #endif

Do you have any ideas please? I don't want to run the 
input files through cpp, because I want to get rid of 
them completely later and stick with the GNU makefiles.

Regards
Alex

PS: Here's my parsing script

#!/usr/bin/perl -w

use strict;
use vars qw($parser $text %top %ifdef);
use Data::Dumper;
use Parse::RecDescent;
$RD_WARN  = 1;
$RD_HINT  = 1;
$RD_TRACE = 120;
$parser = Parse::RecDescent->new(q(

mmpfile: chunk(s) /^\Z/
chunk: assignment | ifdef | <error>

assignment: keyword <skip: '[ \t]+'> value(s) {
        push @{$::top{uc $item{keyword}}}, @{$item[-1]};
}

ifdef: /#\s*if/ expression
                chunk(s?)
       /#\s*endif/

expression: '!' defined_expr | defined_expr
defined_expr: 'defined' '(' value ')' | 'defined' value | '(' conjunction ')'
conjunction: disjunction(s /&&/)
disjunction: expression(s /\|\|/)

value:   /VAL\d+\b/i
keyword: /KEY\d+\b/i

)) or die 'Bad grammar';
$text .= $_ while (<DATA>);
defined $parser->mmpfile($text) or die 'Bad text';
print STDERR Data::Dumper->Dump([\%top, \%ifdef], [qw(top ifdef)]);

__DATA__

#if ! ( (defined ( val3 ) ) || ( ! defined (val4) ) )
key2            val5
#endif

#if ! defined val1
key1            val2
#endif




reply via email to

[Prev in Thread] Current Thread [Next in Thread]