# New Ticket Created by  Reini Urban 
# Please include the string:  [perl #57548]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=57548 >


---
osname= cygwin
osvers= 1.5.25(0.15642)
arch=   cygwin-thread-multi-64int
cc=     gcc
---
Flags:
       category=utilities
       severity=medium
       ack=no
---

Makefile #CONDITIONED_LINE is very limited.
One cannot express conditions on multiple or conflicting keys.

Attached patch starts with adding support to parse
#+(key1 key2...) which expands to #+(or key1 key2...)
where the OR is logically evaluated for all given subexpressions.
Other possible expressions start with (and ...) and (not ...).
This is the same syntax as in the common lisp macro expander, which 
checks *features*. We check for the truth of config keys and hopefully 
in the future for the platform name and config values.

The current logic just checks the logical truth of the hash value 
(exists and not empty).
TODO: also check the platform name if the hash key does not exist
TODO: recursive (), evaluate AND, OR, NOT with multiple keys
   keys are space seperated
TODO: check for key=value, like #+(ld=gcc)
TODO: recursive (), evaluate AND, OR, NOT with multiple keys.

doc:
If conditioned_lines is true, then lines in the file that begin with
C<#+(var):> are skipped if the var condition is false.
Lines that begin with C<#-(var):> are skipped if the var condition is true.

A condition var may be a single keyword, which is true if a config key 
is true or the platform name, or a logical combination or (and var1 
var2...) or (or var1 var2...) or (not var1...),
as in common lisp macro expansion, with OR being the default for 
multiple keys.
Keys are space seperated.
Keys may also consist of key=value pairs, where the key is checked for 
equalness to the value. Note that values may contain no spaces here. 
(TODO: support quotes in values)

   #+(var1 var2...) defaults to #+(or var1 var2...)
   #-(var1 var2...) defaults to #-(or var1 var2...)

For instance:

   #+(win32): $(SRC_DIR)/atomic/gcc_x86$(O)

will be processed if the platform is win32.

   #-(win32 cygwin): $(SRC_DIR)/atomic/gcc_x86$(O)

will be skipped if the platform is win32 or cygwin.

   #+(and win32 glut (not cygwin)):

will be used on win32 and if glut is defined, but not on cygwin.

---
Summary of my parrot 0.6.4 (r0) configuration:
        configdate='Sat Jul 19 10:18:22 2008 GMT'
        Platform:
          osname=cygwin, archname=cygwin-thread-multi-64int
          jitcapable=1, jitarchname=i386-cygwin,
          jitosname=CYGWIN, jitcpuarch=i386
          execcapable=1
          perl=/usr/bin/perl.exe
        Compiler:
          cc='gcc', ccflags='-U__STRICT_ANSI__  -pipe -I/usr/local/include
-DHASATTRIBUTE_CONST  -DHASATTRIBUTE_DEPRECATED  -DHASATTRIBUTE_MALLOC
-DHASATTRIBUTE_NONNULL  -DHASATTRIBUTE_NORETURN  -DHASATTRIBUTE_PURE
-DHASATTRIBUTE_UNUSED  -DHASATTRIBUTE_WARN_UNUSED_RESULT
-falign-functions=16 -maccumulate-outgoing-args -W -Wall
-Waggregate-return -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment
-Wdisabled-optimization -Wendif-labels -Wextra -Wformat
-Wformat-extra-args -Wformat-nonliteral -Wformat-security -Wformat-y2k
-Wimplicit -Wimport -Winit-self -Winline -Winvalid-pch -Wmissing-braces
-Wno-missing-format-attribute -Wpacked -Wparentheses -Wpointer-arith
-Wreturn-type -Wsequence-point -Wno-shadow -Wsign-compare
-Wstrict-aliasing -Wstrict-aliasing=2 -Wswitch -Wswitch-default
-Wtrigraphs -Wundef -Wunknown-pragmas -Wno-unused -Wwrite-strings
-Wbad-function-cast -Wdeclaration-after-statement
-Wimplicit-function-declaration -Wimplicit-int -Wmain
-Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wnonnull
-DDISABLE_GC_DEBUG=1 -DNDEBUG -O3 -DHAS_GETTEXT',
        Linker and Libraries:
          ld='gcc', ldflags=' -Wl,--enable-auto-import
-Wl,--export-all-symbols -Wl,--stack,8388608
-Wl,--enable-auto-image-base -L/usr/local/lib',
          cc_ldflags='',
          libs='-lcrypt -lgmp -lreadline -lpcre /usr/bin/glut32.dll -lglu32
-lopengl32 -lcrypto -lintl'
        Dynamic Linking:
          share_ext='.dll', ld_share_flags='-shared',
          load_ext='.dll', ld_load_flags='-shared'
        Types:
          iv=long, intvalsize=4, intsize=4, opcode_t=long, opcode_t_size=4,
          ptrsize=4, ptr_alignment=1 byteorder=1234,
          nv=double, numvalsize=8, doublesize=8
        Locally applied patches:
           [perl #51944] [DOCS]  Cygwin Readme
           [perl #56562] [PATCH] root.in: add cygwin importlib
           [perl #56544] [PATCH] install_files.pl
           [perl #56558] [PATCH] pdb rename to parrot_pdb
           [perl #56998] [TODO]  rename cygwin dll to cygparrot.dll
           [perl #57006] [PATCH] add cygwin opengl config quirks
           [perl #57110] [PATCH] ncurses for cygwin
           [perl #57112] [PATCH] postgres for cygwin
           [perl #57114] [PATCH] urm RealBin issue
---
Environment:
           CYGWIN =server
           HOME =/home/rurban
           LANG  (unset)
           LANGUAGE  (unset)
           LD_LIBRARY_PATH  (unset)
           LOGDIR  (unset)
           PATH
=~/bin:/usr/bin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/usr/bin:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Programme/ATI

Technologies/ATI.ACE/Core-Static:/usr/local/bin:/usr/lib/gstreamer-0.8:/usr/lib/lapack
           SHELL  (unset)


Index: lib/Parrot/Configure/Compiler.pm
===================================================================
--- lib/Parrot/Configure/Compiler.pm	(revision 29965)
+++ lib/Parrot/Configure/Compiler.pm	(working copy)
@@ -183,15 +183,38 @@
 
 =item conditioned_lines
 
-If conditioned_lines is true, then lines in the file that begin with:
-C<#CONDITIONED_LINE(var):> are skipped if the var condition is false. Lines
-that begin with C<#INVERSE_CONDITIONED_LINE(var):> are skipped if
-the var condition is true.  For instance:
+If conditioned_lines is true, then lines in the file that begin with
+C<#+(var):> are skipped if the var condition is false.
+Lines that begin with C<#-(var):> are skipped if the var condition is true.
+For legacy the old syntax #CONDITIONED_LINE(var): and #INVERSE_CONDITIONED_LINE(var):
+is also supported.
 
-  #CONDITIONED_LINE(win32): $(SRC_DIR)/atomic/gcc_x86$(O)
+A condition var may be a single keyword, which is true if a config key is true
+or equal to the platform name,
+or a logical combination or (and var1 var2...) or (or var1 var2...) or (not var1...)
+as in common lisp macro expansion, OR being the default for multiple keys.
+Keys are space seperated.
+Keys may also consist of key=value pairs, where the key is checked for equalness
+to the value. Note that values may contain no spaces here. (TODO: support quotes
+in values)
 
+  #+(var1 var2...) defaults to #+(or var1 var2...)
+  #-(var1 var2...) defaults to #-(or var1 var2...)
+
+For instance:
+
+  #+(win32): $(SRC_DIR)/atomic/gcc_x86$(O)
+
 will be processed if the platform is win32.
 
+  #-(win32 cygwin): $(SRC_DIR)/atomic/gcc_x86$(O)
+
+will be skipped if the platform is win32 or cygwin.
+
+  #+(and win32 glut (not cygwin)):
+
+will be used on win32 and if glut is defined, but not on cygwin.
+
 =item comment_type
 
 This option takes has two possible values, C<#> or C</*>. If present and
@@ -321,12 +344,20 @@
             last;
         }
         if ( $options{conditioned_lines} ) {
-            if ( $line =~ m/^#CONDITIONED_LINE\(([^)]+)\):(.*)/s ) {
-                next unless $conf->data->get($1);
+	    # allow nested parens here
+            if ( $line =~ m/^#([-+])\((.+)\):(.*)/s ) {
+		my $truth = cond_eval($conf, $2);
+		next if ($1 eq '-') and $truth;
+		next if ($1 eq '+') and not $truth;
+                $line = $3;
+	    }
+	    # but here not (legacy)
+	    elsif ( $line =~ m/^#CONDITIONED_LINE\(([^)]+)\):(.*)/s ) {
+                next unless cond_eval($1);
                 $line = $2;
             }
             elsif ( $line =~ m/^#INVERSE_CONDITIONED_LINE\(([^)]+)\):(.*)/s ) {
-                next if $conf->data->get($1);
+                next if cond_eval($1);
                 $line = $2;
             }
         }
@@ -426,6 +457,18 @@
     move_if_diff( "$target.tmp", $target, $options{ignore_pattern} );
 }
 
+# Just checks the logical truth of the hash value (exists and not empty)
+# TODO: also check the platform name if the hash key does not exist
+# TODO: recursive (), evaluate AND, OR, NOT with multiple keys
+# TODO: check for key=value, like #+(ld=gcc)
+sub cond_eval {
+    my $conf = shift;
+    my $expr = shift;
+    # TODO: parse for parens and multiple keys in the expression and
+    # evaluate it recursively.
+    return $conf->data->get($expr);
+}
+
 sub append_configure_log {
     my $conf = shift;
     my $target = shift;

Reply via email to