Home > Raku > Dodging segfaults

Dodging segfaults

While fighting with NativeCall to get github-flavoured-markdown to work, I stepped onto a nice idiom. As many C-libs, cmark-gfm does enjoy enums that hide bitmasks. They have to do that because C doesn’t sport named arguments. Raku does and hence a nice interface would not ask for binary operations on the caller side.

markdown-gfm-to-html('# Heading 1', :UNSAFE, :HARDBREAKS, :FULL_INFO_STRING);

Now I need a way to turn the named arguments into a list so I can use that as keys in of enum. A Capture in the signature of the sub will do the trick.

multi sub markdown-gfm-to-html(Str:D $str, |opts ( :$DEFAULT, :$SOURCEPOS, :$HARDBREAKS, :$SAFE, :$UNSAFE, :$NOBREAKS, :$NORMALIZE, :$VALIDATE_UTF8, :$SMART, :$GITHUB_PRE_LANG, :$LIBERAL_HTML_TAG, :$FOOTNOTES, :$STRIKETHROUGH_DOUBLE_TILDE, :$TABLE_PREFER_STYLE_ATTRIBUTES, :$FULL_INFO_STRING ) --> Str:D) {
    enum CMARK_OPTIONS (
        DEFAULT => 0,
        SOURCEPOS =>  1 +< 1,
        HARDBREAKS  => 1 +< 2,
        SAFE => 1 +< 3,
        UNSAFE => 1 +< 17,
        NOBREAKS => 1 +< 4,
        NORMALIZE => 1 +< 8,
        VALIDATE_UTF8 => 1 +< 9 ,
        SMART => 1 +< 10,
        GITHUB_PRE_LANG => 1 +< 11,
        LIBERAL_HTML_TAG => 1 +< 12,
        FOOTNOTES => 1 +< 13,
        STRIKETHROUGH_DOUBLE_TILDE => 1 +< 14,
        TABLE_PREFER_STYLE_ATTRIBUTES => 1 +< 15,
        FULL_INFO_STRING => 1 +< 16
    );

    my $opts = [+|] CMARK_OPTIONS::{opts.hash.keys}».Numeric;

    cmark_markdown_to_html($str, $str.encode('utf-8').bytes, $opts);
}

Raku allows us to store part of a Signature in a Capture. The latter will be transparent for the caller of the Callable. Having to use a hyper-method-call-operator isn’t that great, so the enum could become a Map to simplify things a bit.

If you wish to use NativeCall, please do! But think of the generations to come that will use your module. Hopefully, they will like C less then our generation does. Segmentation faults are not -Ofun.

Categories: Raku
  1. Clifton Wood
    September 10, 2023 at 20:30

    I wonder if there will be a way to make this part…

    `|opts ( :$DEFAULT, :$SOURCEPOS, :$HARDBREAKS, :$SAFE, :$UNSAFE, :$NOBREAKS, :$NORMALIZE, :$VALIDATE_UTF8, :$SMART, :$GITHUB_PRE_LANG, :$LIBERAL_HTML_TAG, :$FOOTNOTES, :$STRIKETHROUGH_DOUBLE_TILDE, :$TABLE_PREFER_STYLE_ATTRIBUTES, :$FULL_INFO_STRING )`

    reusable? I would rather not have to go the full RakuAST on it, but macros would be nice. I would consider attempting this with the existing proto-macros, but I haven’t had much luck with them.

  1. September 11, 2023 at 13:59

Leave a comment