OpenGL-Modern

 view release on metacpan or  search on metacpan

utils/common.pl  view on Meta::CPAN

    error_check => ($name eq "glGetError") ? "" : qq{OGLM_CHECK_ERR("$name", )},
    avail_check => $avail_check,
    beforecall => '',
    retcap => ($isvoid ? '' : 'RETVAL = '),
    retnames => ($isvoid ? [] : ['$retval']),
    callarg_list => $callarg_list,
    error_check2 => ($name eq "glGetError") ? "" : qq{OGLM_CHECK_ERR("$name", )},
    aftercall => '',
    retout => ($isvoid ? '' : "\nOUTPUT:\n  RETVAL"),
  );
  my @ret = \%default;
  my %dynlang = %{ $s->{dynlang} || {} };
  return @ret if !@ptr_arg_inds or !%dynlang;
  my %pbinding = (%default, binding_name => $name . '_p',
    aliases => [ map "${_}_p", sort keys %{ $s->{aliases} || {} } ],
  );
  @ptr_arg_inds = grep $_ >= 0, @ptr_arg_inds;
  my %name2data = map +($_->[0] => $_), @argdata;
  my %name2parsed = map +($_->[0] => parse_ptr($_)), @argdata[@ptr_arg_inds];
  die "$name: undefined dynlang arg '$_'" for grep /^[a-z]/ && !exists $name2data{$_}, keys %dynlang;
  my %this = %pbinding;
  my $cleanup = delete $dynlang{CLEANUP} // '';
  my %indynlang = %dynlang;
  my %is_inarg = map +($_->[0]=>1), @argdata;
  if (my @outaslist = grep $indynlang{$_} =~ /\bOUTASLIST\b/, keys %indynlang) {
    die "$name: >1 OUTASLIST (@outaslist)" if @outaslist > 1;
    die "$name: no OUTASLIST len" unless my ($len) = $indynlang{$outaslist[0]} =~ /\bOUTASLIST:([^\s,]+)/;
    my $parsed = $name2parsed{$outaslist[0]};
    die "$name: no typefunc for $outaslist[0]" unless my $typefunc = typefunc($parsed->[0]);
    my $newfunc = 'newSV' . lc substr $typefunc, 0, 2;
    $dynlang{$outaslist[0]} = "OGLM_ALLOC($len,$parsed->[0],$outaslist[0])";
    $cleanup .= "free($outaslist[0]);";
    $dynlang{OUTPUT} = "OGLM_OUT_FINISH($outaslist[0],$len,$newfunc)";
    $this{retnames} = ["\@$outaslist[0]"];
  }
  my @sized = grep $indynlang{$_} =~ /\bSIZE\b/, keys %indynlang;
  my %arg2lenoverride;
  for my $arg (@sized) {
    die "$name: failed to get SIZE info from '$indynlang{$arg}'" unless
      my ($compsize_group, $compsize_from, $mult) =
        $indynlang{$arg} =~ /\bSIZE:([^:]+):([^,:\s]+)(?::([^,\s]+))?/;
    $mult ||= 1;
    my $parsed = $name2parsed{$arg};
    $arg2lenoverride{$arg} = ["${compsize_from}_count", "OGLM_SIZE_ENUM($compsize_group,$compsize_from,$mult)"];
    $dynlang{$arg} = "OGLM_ALLOC(${compsize_from}_count,$parsed->[0],$arg)";
  }
  die "$name: cannot have both RETVAL and OUTPUT" if $dynlang{OUTPUT} and $dynlang{RETVAL};
  if (my $retval = delete $dynlang{RETVAL}) {
    die "$name: dynlang RETVAL '$retval' not arg to function" if !defined $name2data{$retval};
    if (($name2data{$retval}[2]//'') eq '1') {
      $this{xs_rettype} = $name2parsed{$retval}[0];
      $this{aftercall} = "\n  RETVAL = $retval\[0];";
    } else {
      $this{xs_rettype} = delete $dynlang{RETTYPE} // $name2data{$retval}[1];
      $this{aftercall} = "\n  RETVAL = $retval;";
    }
    $this{retout} = "\nOUTPUT:\n  RETVAL";
    $this{retnames} = ["\$$retval"];
  } elsif (my $output = delete $dynlang{OUTPUT}) {
    $this{aftercall} = "\n  $output";
    $this{xs_code} = "PPCODE:\n";
  } elsif (grep $indynlang{$_} =~ /\bOUT(?:ARRAY|SCALAR)\b/, keys %indynlang) {
    my @retnames = map $indynlang{$_} =~ /\bOUTSCALAR\b/ ? ['$',$_] :
      $indynlang{$_} =~ /\bOUTARRAY\b/ ? ['\\@',$_] :
      (), grep $indynlang{$_}, map $_->[0], @argdata;
    $this{retnames} = [ $isvoid ? () : '$retval', map join('', @$_), @retnames ];
    $this{xs_code} = "PPCODE:\n";
    my $aftercall = "EXTEND(sp, ".(@{ $this{retnames} }).");";
    if (!$isvoid) {
      my $newval = $s->{restype} =~ /^\s*void\s*\*\s*$/ ? "newSViv(PTR2IV(RETVAL))" : "newSV".lc(substr typefunc($s->{restype}), 0, 2)."(RETVAL)";
      $aftercall .= "\n  mPUSHs($newval);";
    }
    for (@retnames) {
      my ($sigil, $arg) = @$_;
      delete $is_inarg{$arg};
      if ($sigil eq '\\@') {
        die "$name: no OUTARRAY len" unless my ($len) = $indynlang{$arg} =~ /\bOUTARRAY:([^\s,]+)/;
        my $parsed = $name2parsed{$arg};
        $dynlang{$arg} = "OGLM_ALLOC($len,$parsed->[0],$arg)";
        my $typefunc = typefunc($name2parsed{$arg}[0]);
        my $newfunc = "newSV".lc(substr $typefunc, 0, 2);
        my $makeav = "OGLM_PUSH_ARRAY($name, $newfunc, $arg, $len)";
        $aftercall .= "\n  $makeav";
        $cleanup .= "free($arg);";
      } else {
        delete $dynlang{$arg};
        my $newval;
        if ($name2parsed{$arg}[0] eq 'void' || is_stringtype($name2data{$arg}[1])) {
          my ($len) = $indynlang{$arg} =~ /\bOUTSCALAR:([^\s,]+)/;
          $len //= 0;
          $newval = "newSVpv($arg,$len)";
        } else {
          my $typefunc = typefunc($name2parsed{$arg}[0]);
          $newval = "newSV".lc(substr $typefunc, 0, 2)."($arg\[0])";
        }
        $aftercall .= "\n  mPUSHs($newval);";
      }
    }
    $this{aftercall} = "\n  $aftercall";
    $this{retout} = "";
  }
  delete @is_inarg{keys %dynlang};
  delete @is_inarg{grep !$name2parsed{$_}[1], keys %name2parsed};
  my %is_inarray;
  for my $arg (sort grep $indynlang{$_} =~ /\bINARRAY:/, keys %indynlang) {
    die "$name: no INARRAY len" unless my ($len) = $indynlang{$arg} =~ /\bINARRAY:([^\s,]+)/;
    $is_inarray{$arg} = $is_inarg{$arg} = 1;
    my $parsed = $name2parsed{$arg};
    my $typefunc = typefunc($parsed->[0]);
    $dynlang{$arg} = "OGLM_GET_ARRAY($arg, $parsed->[0], $typefunc, $len)";
    $cleanup .= "free($arg);";
  }
  my $beforecall = '';
  for my $get (sort grep $dynlang{$_} =~ /^</, keys %dynlang) {
    my $val = delete $dynlang{$get};
    $val =~ s#^<##;
    my ($getfunc) = $val =~ /^(\w+)/;
    $val =~ s#&(?![\{\(a-z])#&$get#;
    my $vardata = $name2data{$get};
    $beforecall .= "  $vardata->[1]$get;\n  $val;\n";
    if (my $glewImpl = $signatures->{$getfunc}{glewImpl}) {
      $this{avail_check} = join "", grep $_, $this{avail_check}, "  OGLM_AVAIL_CHECK($glewImpl, $getfunc)\n";
    }
  }
  for my $len (sort grep $dynlang{$_} =~ /\bLEN:/, keys %dynlang) {
    my $val = delete $dynlang{$len};
    die "$name: failed to parse LEN '$val'" unless my ($varname) = $val =~ /\bLEN:([^,\s]+)/;



( run in 0.662 second using v1.01-cache-2.11-cpan-5511b514fd6 )