OpenPKG CVS Repository
  http://cvs.openpkg.org/
  ____________________________________________________________________________

  Server: cvs.openpkg.org                  Name:   Michael van Elst
  Root:   /e/openpkg/cvs                   Email:  [EMAIL PROTECTED]
  Module: openpkg-re                       Date:   12-Nov-2002 12:23:28
  Branch: HEAD                             Handle: 2002111211232700

  Modified files:
    openpkg-re              openpkg-index

  Log:
    store conditions in UPN
    support && and ! in #if (no operator precedences between || and &&)
    added comments

  Summary:
    Revision    Changes     Path
    1.3         +80 -15     openpkg-re/openpkg-index
  ____________________________________________________________________________

  Index: openpkg-re/openpkg-index
  ============================================================
  $ cvs diff -u -r1.2 -r1.3 openpkg-index
  --- openpkg-re/openpkg-index  12 Nov 2002 08:15:36 -0000      1.2
  +++ openpkg-re/openpkg-index  12 Nov 2002 11:23:27 -0000      1.3
  @@ -60,10 +60,41 @@
       return $v;
   }
   
  -sub paren ($) {
  -    my($s) = @_;
  -    $s = "($s)" if $s !~ /^\(/ && $s =~ / & | \|/;
  -    return $s;
  +sub upn ($) {
  +    my($t) = @_;
  +    my(@tok) = $t =~ /(\(|\)|\&\&|\|\||\!|\S+)/g;
  +    my(@out,$op,$o);
  +    my(@save);
  +
  +    $op = [];
  +    foreach (@tok) {
  +        if ($_ eq '(') {
  +            push @save, $op;
  +            $op = [];
  +        } elsif ($_ eq ')') {
  +            die "FATAL: unresolved operators in: @tok\n" if @$op;
  +            $op = pop @save
  +                or die "FATAL: parenthesis stack underflow in: @tok\n";
  +            while ($o = pop @$op) {
  +                push @out, $o->[0];
  +                last if $o->[1];
  +            }
  +        } elsif ($_ eq '&&') {
  +            push @$op, [ '+', 1 ] ;
  +        } elsif ($_ eq '||') {
  +            push @$op, [ '|', 1 ] ;
  +        } elsif ($_ eq '!') {
  +            push @$op, [ '!', 0 ];
  +        } elsif (/^\%\{(\S*?)\}$/) {
  +            push @out, $1;
  +            while ($o = pop @$op) {
  +                push @out, $o->[0];
  +                last if $o->[1]; # binop
  +            }
  +        }
  +    }
  +
  +    return join (' ',@out);
   }
   
   #
  @@ -95,6 +126,10 @@
       $s =~ s/^#\{\!\?([^:]*):\s*%(.*?)\s*\}\s*$/#ifndef $1\n#$2\n#endif/mg;
       $s =~ s/^#\{\!\?([^:]*):\s*(.*?)\s*\}\s*$/#ifndef $1\n$2\n#endif/mg;
   
  +    #
  +    # guess what parameters are external conditions by scanning
  +    # for "default" sections.
  +    #
       $re = '^\#ifndef\s+[\w\_]+\s*\n((?:\#define\s+[\w\_]+\s.*\n)+)\#endif\n';
       @defs = $s =~ /$re/gm;
       foreach (@defs) {
  @@ -114,29 +149,52 @@
           $v = vsub(\%var,$l);
   
           if (($p) = $v =~ /^\#if\s+(.*?)\s*$/) {
  +
  +            #
  +            # normalize #if expressions
  +            # "%{variable}" == "yes"
  +            # "%{variable}" == "no"
  +            # operators ! && ||
  +            #
               $term = '';
  -            while ($p =~ /(?:(\|\|)|"\%\{([^}]+)\}"\s*==\s*"(yes|no)")/g) {
  +            while ($p =~ 
/(?:(\!|\|\||\&\&|\(|\))|"\%\{([^}]+)\}"\s*==\s*"(yes|no)")/g) {
                   if (defined $1) {
  -                    $term .= ' | ';
  +                    $term .= " $1 ";
                   } elsif (exists $evar{$2}) {
  -                    $term .= ($3 eq 'no' ? '!' : '').vsub(\%evar,$evar{$2});
  +                    $term .= ($3 eq 'no' ? '! ' : '').vsub(\%evar,$evar{$2});
                   } else {
                       die "ERROR: unknown conditional: $l\n== $v\n";
                   }
               }
  +
  +            #
  +            # join with previous conditions for this #if/#endif block
  +            #
               if ($term ne '') {
  -                push @term, paren($term);
  -                $cond = join(' + ',sort @term).'';
  +                push @term, "( $term )";
  +                $cond = join(' && ',sort @term).'';
               }
           } elsif ($v =~ /^\#endif\s*$/) {
  +            #
  +            # unwind last #if expression
  +            #
               pop @term;
               $cond = join(' + ',sort @term).'';
  +
           } elsif ($v =~ /^\#(?:define)\s*(\S+)\s*(.*?)\s*$/) {
  +
  +            #
  +            # define conditional variables
  +            # truth-value becomes current condition
  +            #
  +            # define internal variables
  +            # -> store for subsequent substitution
  +            #
               if (exists $evar{$1}) {
                   if ($2 eq 'yes') {
  -                    $evar{$1} = paren($cond);
  +                    $evar{$1} = "( \%\{$1\} || ( $cond ) )";
                   } elsif ($2 eq 'no') {
  -                    $evar{$1} = '!'.paren($cond);
  +                    $evar{$1} = "( %\{$1\} && ! ( $cond ) )";
                   } else {
                       die "ERROR: logic too complex: $l\n== $v\n";
                   }
  @@ -144,6 +202,10 @@
                   $var{$1} = $2;
               }
           } elsif ($v =~ /^\s*([^\#]\S*)\s*:\s*(.*?)\s*$/) {
  +
  +            #
  +            # store attribute=value for current condition
  +            #
               push @{$attr{$1}->{$cond}}, commasep($1,$2);
           }
       }
  @@ -230,14 +292,15 @@
   #
   sub xml_tag ($$$;$) {
       my($i,$a,$k,$tag) = @_;
  -    my($out,$cond);
  +    my($out,$cond,$upn);
       return "" unless exists $a->{$k};
       $tag = $k unless defined $tag;
       $out = '';
   
       foreach $cond (sort keys %{$a->{$k}}) {
  +        $upn = e(upn($cond));
           $out .= (' ' x $i).
  -            ($cond ne '' ?  "<$tag cond=\"$cond\">" : "<$tag>").
  +            ($cond ne '' ?  "<$tag cond=\"$upn\">" : "<$tag>").
               join("\n", map { e($_) } @{$a->{$k}->{$cond}}).
               "</$tag>\n";
       }
  @@ -253,14 +316,15 @@
   #
   sub xml_bag ($$$;$) {
       my($i,$a,$k,$tag) = @_;
  -    my($out,$cond);
  +    my($out,$cond,$upn);
       return "" unless exists $a->{$k};
       $tag = $k unless defined $tag;
       $out = '';
   
       foreach $cond (sort keys %{$a->{$k}}) {
  +        $upn = e(upn($cond));
           $out .= (' ' x $i).
  -                ($cond ne '' ? "<$tag cond=\"$cond\">\n" : "<$tag>\n").
  +                ($cond ne '' ? "<$tag cond=\"$upn\">\n" : "<$tag>\n").
                   (' ' x ($i+2))."<rdf:bag>\n".
                   join("",
                        map { (' ' x ($i+4))."<rdf:li>".e($_)."</rdf:li>\n" }
  @@ -361,3 +425,4 @@
       }
   }
   xml_foot(\*STDOUT);
  +
______________________________________________________________________
The OpenPKG Project                                    www.openpkg.org
CVS Repository Commit List                     [EMAIL PROTECTED]

Reply via email to