On Nov 8, 2011, at 06:50 , Martin Hansen wrote:

> Sylvester Keil wrote in post #1030842:
> 
> How could I know that bulder.c -> builder.prefix changed the function an 
> instance method to a "function"?

Well, first, because I showed you:

>> Because you're passing too few arguments to the function (6 to 7 arity function):
>> 
>> static
>> VALUE backtrack(VALUE self, VALUE _ss, VALUE _s, VALUE _p, VALUE _mm, VALUE _ins, VALUE _del)
>> 
>> vs:
>> 
>>    backtrack(ss, s + 1, p + 1, mm - 1, ins, del)))
>> 
>> Since you're not actually using self for anything, there is no reason for this to be a registered method. You might want to add this to the prefix section.

> I am pretty desperate for some reading 
> - and examples - on this matter! Something modern (i. e. Ruby 1.9) and omething that is about inline C and not necessarily all of Ruby's API.

If you find the documentation insufficient in some way, please file a ticket. I can only improve what I  know about.

> I changed the code and cleaned up a few things:
> 
> Ruby code: http://pastie.org/2831055
> Inline code: http://pastie.org/2831058
> 
> Now I get a warning - and the wrong output:
> 
> /Users/maasha/.ruby_inline/Inline_Scan_5319.c: In function 'backtrack':
> /Users/maasha/.ruby_inline/Inline_Scan_5319.c:38: warning: implicit 
> conversion shortens 64-bit value into a 32-bit value
> false

I don't. Here is what I wound up with:

#!/usr/bin/env ruby

require 'pp'
require 'inline'

class Scan
  def initialize(seq)
    @seq = seq
  end

  inline do |builder|
    builder.prefix %{
      #define MATCH(A,B) ((equal[(A)] & equal[(B)]) != 0)
    }

    builder.add_static "id_seq", 'rb_intern("@seq")', "ID"

    builder.prefix %{
      int equal[256] = {
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 1,14, 4,11, 0, 0, 8, 7, 0, 0,10, 0, 5,15, 0,
          0, 0, 9,12, 2, 2,13, 3, 0, 6, 0, 0, 0, 0, 0, 0,
          0, 1,14, 4,11, 0, 0, 8, 7, 0, 0,10, 0, 5,15, 0,
          0, 0, 9,12, 2, 2,13, 3, 0, 6, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
      };
    }

    # ss is the start of the string, used only for reporting the match endpoints.
    builder.prefix %{
      int backtrack(char* ss, char* s, char* p, int mm, int ins, int del)
      {
          int r = 0;

          while (*s && MATCH(*s, *p)) ++s, ++p;    // OK to always match longest segment

          if (!*p)
              return (s - ss) - 1;
          else
          {
              if (mm && *s && *p && (r = backtrack(ss, s + 1, p + 1, mm - 1, ins, del))) return r;
              if (ins && *s &&      (r = backtrack(ss, s + 1, p, mm, ins - 1, del)))     return r;
              if (del && *p &&      (r = backtrack(ss, s, p + 1, mm, ins, del - 1)))     return r;
          }

          return 0;
      }
    }

    # Find all occurrences of p starting at any position in s, with at most
    # mm mismatches, ins insertions and del deletions.
    builder.c %{
      int patscan(char* p, int mm, int ins, int del)
      {
          VALUE seq = rb_ivar_get(self, id_seq);
          char* s = StringValuePtr(seq);
          char* ss;
          int   nnd;

          for (ss = s; *s; ++s)
          {
              nnd = backtrack(ss, s, p, mm, ins, del);

              if (nnd)
                 return nnd;
          }
       }
    }
  end
end

seq = "tcatcgagtcatcgatcgatcgatcgatcga"
pat = "gtcatcga"

scanner = Scan.new(seq)

puts scanner.patscan(pat, 0, 0, 0)