Hardware-Vhdl-Automake

 view release on metacpan or  search on metacpan

lib/Hardware/Vhdl/Automake/PreProcessor/Cish.pm  view on Meta::CPAN

        if (defined $state->{endat}) { $rem = $state->{endat} - tell($state->{fhi}) } # REMainding bytes we are allowed to read from the file
        if ( $state->{$bufname} =~ m/^(.*?(\015\012?|\012\015?))(.*)$/s ) {
            $state->{line}     = $1;
            $state->{$bufname} = $3;
        } elsif ( exists $state->{fhi} && !eof $state->{fhi} && (!defined $rem || ($rem > 0))) {
            local $/ = \$file_slurp_limit;
            if (defined $rem && $file_slurp_limit > $rem) { $/ = \$rem }
            $state->{$bufname} .= readline $state->{fhi};
            redo GET_LINE;
        } else {
            $state->{line}     = $state->{$bufname};
            $state->{$bufname} = '';
        }
    }
    $state->{line} = undef if $state->{line} eq '';
}

sub macro_define {
    my ($self, $macname, $macdef) = @_;
    my $perm  = $self->[0];
    $macdef = '' if !defined $macdef;
    if (exists $perm->{macros}{$macname}) {
        carp "Macro '$macname', defined at $perm->{macros}{$macname}{defined_in} line $perm->{macros}{$macname}{linenum}, was redefined";
    }
    $perm->{macros}{$macname} = { search => $macname, replace => $macdef, defined_in => $self->[-1]{source}, defined_line => $self->[-1]{linenum} };
    $self->update_macro_re;
}

sub macro_define_func {
    my ($self, $macname, $fargs, $macdef) = @_;
    $fargs =~ s/\s+//g;
    my @args = split(',', $fargs);
    my $arg_re = join '|', @args;
    #print "# macro function define: name='$macname', arg re='$arg_re', definition='$macdef'\n";
    $self->[0]{macros}{$macname.'('.scalar(@args)} = {
        search => $macname.'(',
        arg_re => qr/^(.*?)\b($arg_re)\b(.*)$/s,
        arg_index => { map { $args[$_] => $_ } 0..$#args },
        replace => $macdef,
        defined_in => $self->[-1]{source},
        defined_line => $self->[-1]{linenum}
      };
    $self->update_macro_re;
}

sub macro_undefine {
    my ($self, $macname) = @_;
    my $perm  = $self->[0];
    delete $perm->{macros}{$macname};
    $self->update_macro_re;
}

sub macro_undefine_func {
    my ($self, $macname, $args) = @_;
    print "# macro function undef: name='$macname', args='$args'\n";
    my @args = split(',', $args);
    delete $self->[0]{macros}{$macname.'('.scalar(@args)};
    $self->update_macro_re;
}

sub update_macro_re {
    my $perm  = shift->[0];
    my @macnames;
    my %macfuncnames;
    for my $search (map { $perm->{macros}{$_}{search} } keys %{$perm->{macros}}) {
        if (substr($search, -1) eq '(') {
            $macfuncnames{quotemeta($search)} = undef;
        } else {
            push @macnames, $search."\\b";
        }
    }
    my $macro_re = join '|', @macnames, keys %macfuncnames;
    #print "# macro regexp = /^(.*?)\\b($macro_re)(.*)\$/s\n";
    $perm->{macro_re} = qr/^ (.*?) ( " | \b(?:$macro_re) ) (.*) $/xs;
}

sub macro_replace {
    # do macro expansion on the non-quoted parts of $state->{line}
    my $self  = shift;
    my $perm  = $self->[0];
    my $state = $self->[-1];
    my $out = $self->_macro_replace_string($state->{line}, []);
    #~ if ( $out =~ m/^(.*?(\015\012?|\012\015?))(.*)$/s ) {
        #~ # deal with multi-line output from macro replacement
        #~ # TBD: doesn't this mean that lines after the first one get processed more than once?
        #~ $state->{line} = $1;
        #~ $perm->{ungot} = $3;
    #~ } else 
    {
        $state->{line} = $out;
    }
}

sub _extract_args {
    my ($self, $line) = @_;
    # Looks for a comma-separated list of args, followed by a ')'.  If found, return the stuff after the ')' and the list of args
    #  if no closing bracket found, returns $line only.
    # Currently needs to find the closing bracket on the current line
    my $in=$line; # text yet to be processed: we nibble this from the left
    my $out=''; # accumulator for bits that have been nibbled and may be added to argument list
    my $bd=0; # bracket depth
    my @args; # arguments found so far
    #print "#> in = '$in'\n";                
    while ($in =~ m/^ (.*?) ( [\(\)\",] ) (.*) $/xms) {
        $out .= $1; # prematch
        my $g = $2; # significant char: bracket, quote or comma
        $in = $3; # postmatch
        if ($g eq ',') {
            if ($bd==0) {
                # a comma, not inside a bracket: what we've found before this must be an argument
                push @args, $out;
                $out = '';
            } else {
                # a comma, from inside a bracket: just add it to the current argument string
                $out .= $g;
            }
        } elsif ($g eq ')') {
            if ($bd==0) {
                # a closing bracket, not inside a bracket: must be the end of the argument list
                return $in, @args, $out;
            } else {



( run in 1.057 second using v1.01-cache-2.11-cpan-bbe5e583499 )