This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
For both opmini.o and perlmini.o define PERL_EXTERNAL_GLOB and PERL_IS_MINIPERL
[perl5.git] / regcomp.pl
index 6a61f98..d85482c 100644 (file)
@@ -85,22 +85,46 @@ sub process_flags {
 
   $ind = 0;
   my @selected;
+  my $bitmap = '';
   do {
-    push @selected, $name[$ind] if $flags[$ind] && $flags[$ind] eq $flag;
+    my $set = $flags[$ind] && $flags[$ind] eq $flag ? 1 : 0;
+    # Whilst I could do this with vec, I'd prefer to do longhand the arithmetic
+    # ops in the C code.
+    my $current = do {
+      no warnings 'uninitialized';
+      ord do {
+       no warnings 'substr';
+       substr $bitmap, ($ind >> 3);
+      }
+    };
+    substr $bitmap, ($ind >> 3), 1, chr($current | ($set << ($ind & 7)));
+
+    push @selected, $name[$ind] if $set;
   } while (++$ind < $lastregop);
   my $out_string = join ', ', @selected, 0;
   $out_string =~ s/(.{1,70},) /$1\n    /g;
+
+  my $out_mask = join ', ', map {sprintf "0x%02X", ord $_} split '', $bitmap;
+
   return $comment . <<"EOP";
-#define REGNODE_\U$varname\E(node) strchr((const char *)PL_${varname}, (node))
+#define REGNODE_\U$varname\E(node) (PL_${varname}_bitmask[(node) >> 3] & (1 << ((node) & 7)))
 
 #ifndef DOINIT
-EXTCONST U8 PL_${varname}[];
+EXTCONST U8 PL_${varname}[] __attribute__deprecated__;
 #else
-EXTCONST U8 PL_${varname}[] = {
+EXTCONST U8 PL_${varname}[] __attribute__deprecated__ = {
     $out_string
 };
 #endif /* DOINIT */
 
+#ifndef DOINIT
+EXTCONST U8 PL_${varname}_bitmask[];
+#else
+EXTCONST U8 PL_${varname}_bitmask[] = {
+    $out_mask
+};
+#endif /* DOINIT */
+
 EOP
 }
 
@@ -232,21 +256,39 @@ EXTCONST char * PL_reg_extflags_name[];
 EXTCONST char * const PL_reg_extflags_name[] = {
 EOP
 
-open my $fh,"<","regexp.h" or die "Can't read regexp.h: $!";
 my %rxfv;
+my %definitions;    # Remember what the symbol definitions are
 my $val = 0;
 my %reverse;
-while (<$fh>) {
-    if (/#define\s+(RXf_\w+)\s+(0x[A-F\d]+)/i) {
-       my $newval = eval $2;
-       if($val & $newval) {
-           die sprintf "Both $1 and $reverse{$newval} use %08X", $newval;
-       }
-        $val|=$newval;
-        $rxfv{$1}= $newval;
-       $reverse{$newval} = $1;
+foreach my $file ("op_reg_common.h", "regexp.h") {
+    open my $fh,"<", $file or die "Can't read $file: $!";
+    while (<$fh>) {
+
+        # optional leading '_'.  Return symbol in $1, and strip it from
+        # rest of line
+        if (s/ \#define \s+ ( _? RXf_ \w+ ) \s+ //xi) {
+            chomp;
+            my $define = $1;
+            s: / \s* \* .*? \* \s* / : :x;    # Replace comments by a blank
+
+            # Replace any prior defined symbols by their values
+            foreach my $key (keys %definitions) {
+                s/\b$key\b/$definitions{$key}/g;
+            }
+            my $newval = eval $_;   # Get numeric definition
+
+            $definitions{$define} = $newval;
+
+            next unless $_ =~ /<</; # Bit defines use left shift
+            if($val & $newval) {
+                die sprintf "Both $define and $reverse{$newval} use %08X", $newval;
+            }
+            $val|=$newval;
+            $rxfv{$define}= $newval;
+            $reverse{$newval} = $define;
+        }
     }
-}    
+}
 my %vrxf=reverse %rxfv;
 printf $out "\t/* Bits in extflags defined: %032b */\n",$val;
 for (0..31) {