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.
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.