Re: Raku -npe command line usage
On Fri, May 8, 2020 at 6:10 PM Fernando Santagata wrote: > raku -e'lines() ==> grep(/^WARN/) ==> sort() ==> reduce({$^a ~ "\n" ~ > $^b}) ==> say()' sample.log > and the reduce call can be written more compactly: reduce({"$^a\n$^b"}) -- Fernando Santagata
Re: Raku -npe command line usage
Maybe? perl6 -e 'lines() ==> grep /^WARN/ ==> sort() ==> join("\n") ==> say();' HTH, Bill. On Fri, May 8, 2020 at 9:10 AM Fernando Santagata wrote: > > raku -e'.say for lines() ==> grep(/^WARN/) ==> sort' sample.log > > is not very satisfying because for the "for" which breaks the flow. > OTOH this > > raku -e'lines().grep(/^WARN/).sort».say' sample.log > > doesn't use the feed operator and this > > raku -e'lines() ==> grep(/^WARN/) ==> sort() ==> say()' sample.log > > outputs a list on one line, not each line on its own. This one works, but it > feels awkward: > > raku -e'lines() ==> grep(/^WARN/) ==> sort() ==> reduce({$^a ~ "\n" ~ $^b}) > ==> say()' sample.log > > On Fri, May 8, 2020 at 5:49 PM yary wrote: >> >> All good ideas so far, in the "more than one way to do it" spirit, can use >> "state" instead of "my", since state only initializes 1st time it's hit. >> >> raku -ne 'state @i;@i.push($_) if .starts-with(q[WARN]); END .say for >> @i.sort' sample.log >> >> Or adapting Brad's answer with the feed operator for fun >> >> raku -e 'for lines() ==> grep /^WARN/ ==> sort() {.say}' sample.log >> >> Now, I didn't want to use 'map' in there, because of a habit of only using >> 'map' when I want the return values. When looping for side-effects only, >> like saying each value in a list, I want to use 'for'. UnFORtunately though >> I cannot find anything as clean looking as >> >> raku -e 'lines() ==> grep /^WARN/ ==> sort() ==> map *.say' sample.log >> >> reading entirely L-to-R which does NOT use map... ideas? >> >> -y >> >> >> On Fri, May 8, 2020 at 10:10 AM William Michels via perl6-users >> wrote: >> > >> > On Fri, May 8, 2020 at 5:16 AM WFB wrote: >> > > >> > > Hi, >> > > >> > > I am trying to write an one-liner to go through all lines in a logfile >> > > and look for an certain key word, store the line and sort them before >> > > printing them out. >> > > >> > > My approach was: >> > > raku -ne "BEGIN {my @i }; @i.push($_); if $_ ~~ /^WARN/; END { >> > > @i.sort.say }" >> > > That does not work because @i does not exist in the if clause. I tried >> > > our @i as well with no luck. >> > > >> > > How can I store data that can be accessed in the END phaser? Or is there >> > > another way to archive it? TIMTOWTDI^^ >> > > >> > > One hint I found was the variable $ and @ respectively. But those >> > > variables are created for each line new... >> > > >> > > >> > > I did not found a help or examples for -npe except raku -h. Is there >> > > more helpful stuff somewhere in doc.raku.org? If so I could'nt find it. >> > > >> > > Thanks, >> > > Wolfgang >> > >> > Hi Wolfgang, >> > >> > This is a first attempt at doing what you want: I'm sure it can be >> > shortened. Since one of your requirements is doing a sort on filtered >> > values stored in an array, I abandoned use of the "-ne" one-liner >> > flag, using "-e" and "for lines()" instead. I also used grep instead >> > of smart-matching: >> > >> > perl6 -e 'my @i; for lines() {if .grep(/^WARN/) -> ($s) >> > {@i.push($s)};}; .say for @i.sort;' >> > >> > Note: the "-> ($s)" section where I store grepped matches comes from a >> > Jonathan Worthington answer found here (thanks Jonathan!): >> > >> > stackoverflow.com/questions/58982745/raku-one-line-expression-to-capture-group-from-string >> > >> > I certainly would be interested to learn if there's a phaser solution >> > to this problem (and I also have a sneaking suspicion that Supply >> > might be useful here... ). >> > >> > HTH, Bill. > > > > -- > Fernando Santagata
Re: Raku -npe command line usage
Ooops forgot the sort... let's golf with the hyper-operator again... raku -ne'push my @i: $_ if .starts-with: q[WARN]; END @i.sort>>.say' sample.log -y On Fri, May 8, 2020 at 1:10 PM yary wrote: > ooh neat! I didn't know. Indeed this works. Thanks Sean! > > raku -ne'push my @i: $_ if .starts-with: q[WARN]; END .say for @i' > sample.log > > -y > > > On Fri, May 8, 2020 at 1:04 PM Sean McAfee wrote: > >> On Fri, May 8, 2020 at 6:53 AM Brad Gilbert wrote: >> >>> So together that would be: >>> >>> raku -ne 'BEGIN my @i; @i.push($_) if /^WARN/; END .say for @i.sort' >>> >> >> Or alternately the main body of the loop can be written: >> >> (my @i).push($_) if /^WARN/; >> >> Or even: >> >> push my @i: $_ if /^WARN/; >> >> It's so nice how Raku essentially compiles the body of these file loops >> into a little subroutine so that the "my" declaration only occurs once, >> unlike how Perl 5 just textually wraps the loop with "while (<>) {" and "}" >> which makes the declaration occur on every iteration. >> >> I originally figured this out when I idly worked up a classic >> word-frequency-count one-liner: >> >> raku -ne '++(my %freq){$_} for m:g/\w+/; END .say for >> %freq.antipairs.sort.reverse' file ... >> >>
Re: Raku -npe command line usage
ooh neat! I didn't know. Indeed this works. Thanks Sean! raku -ne'push my @i: $_ if .starts-with: q[WARN]; END .say for @i' sample.log -y On Fri, May 8, 2020 at 1:04 PM Sean McAfee wrote: > On Fri, May 8, 2020 at 6:53 AM Brad Gilbert wrote: > >> So together that would be: >> >> raku -ne 'BEGIN my @i; @i.push($_) if /^WARN/; END .say for @i.sort' >> > > Or alternately the main body of the loop can be written: > > (my @i).push($_) if /^WARN/; > > Or even: > > push my @i: $_ if /^WARN/; > > It's so nice how Raku essentially compiles the body of these file loops > into a little subroutine so that the "my" declaration only occurs once, > unlike how Perl 5 just textually wraps the loop with "while (<>) {" and "}" > which makes the declaration occur on every iteration. > > I originally figured this out when I idly worked up a classic > word-frequency-count one-liner: > > raku -ne '++(my %freq){$_} for m:g/\w+/; END .say for > %freq.antipairs.sort.reverse' file ... > >
Re: Raku -npe command line usage
On Fri, May 8, 2020 at 6:53 AM Brad Gilbert wrote: > So together that would be: > > raku -ne 'BEGIN my @i; @i.push($_) if /^WARN/; END .say for @i.sort' > Or alternately the main body of the loop can be written: (my @i).push($_) if /^WARN/; Or even: push my @i: $_ if /^WARN/; It's so nice how Raku essentially compiles the body of these file loops into a little subroutine so that the "my" declaration only occurs once, unlike how Perl 5 just textually wraps the loop with "while (<>) {" and "}" which makes the declaration occur on every iteration. I originally figured this out when I idly worked up a classic word-frequency-count one-liner: raku -ne '++(my %freq){$_} for m:g/\w+/; END .say for %freq.antipairs.sort.reverse' file ...
Re: Raku -npe command line usage
I like this formulation Fernando posted (removed a set of parens not needed with method calls) raku -e'lines.grep(/^WARN/).sort».say' sample.log It is clean, all left-to-right, and doesn't use "map" for its side-effects only. Putting the feed operator back in where it would work–have to keep the hyper-operator– raku -e'(lines() ==> grep(/^WARN/) ==> sort)».say' sample.log -y On Fri, May 8, 2020 at 12:10 PM Fernando Santagata < nando.santag...@gmail.com> wrote: > raku -e'.say for lines() ==> grep(/^WARN/) ==> sort' sample.log > > is not very satisfying because for the "for" which breaks the flow. > OTOH this > > raku -e'lines().grep(/^WARN/).sort».say' sample.log > > doesn't use the feed operator and this > > raku -e'lines() ==> grep(/^WARN/) ==> sort() ==> say()' sample.log > > outputs a list on one line, not each line on its own. This one works, but > it feels awkward: > > raku -e'lines() ==> grep(/^WARN/) ==> sort() ==> reduce({$^a ~ "\n" ~ > $^b}) ==> say()' sample.log > > On Fri, May 8, 2020 at 5:49 PM yary wrote: > >> All good ideas so far, in the "more than one way to do it" spirit, can >> use "state" instead of "my", since state only initializes 1st time it's hit. >> >> raku -ne 'state @i;@i.push($_) if .starts-with(q[WARN]); END .say >> for @i.sort' sample.log >> >> Or adapting Brad's answer with the feed operator for fun >> >> raku -e 'for lines() ==> grep /^WARN/ ==> sort() {.say}' sample.log >> >> Now, I didn't want to use 'map' in there, because of a habit of only >> using 'map' when I want the return values. When looping for side-effects >> only, like saying each value in a list, I want to use 'for'. UnFORtunately >> though I cannot find anything as clean looking as >> >> raku -e 'lines() ==> grep /^WARN/ ==> sort() ==> map *.say' sample.log >> >> reading entirely L-to-R which does NOT use map... ideas? >> >> -y >> >> >> On Fri, May 8, 2020 at 10:10 AM William Michels via perl6-users < >> perl6-users@perl.org> wrote: >> > >> > On Fri, May 8, 2020 at 5:16 AM WFB wrote: >> > > >> > > Hi, >> > > >> > > I am trying to write an one-liner to go through all lines in a >> logfile and look for an certain key word, store the line and sort them >> before printing them out. >> > > >> > > My approach was: >> > > raku -ne "BEGIN {my @i }; @i.push($_); if $_ ~~ /^WARN/; END { >> @i.sort.say }" >> > > That does not work because @i does not exist in the if clause. I >> tried our @i as well with no luck. >> > > >> > > How can I store data that can be accessed in the END phaser? Or is >> there another way to archive it? TIMTOWTDI^^ >> > > >> > > One hint I found was the variable $ and @ respectively. But those >> variables are created for each line new... >> > > >> > > >> > > I did not found a help or examples for -npe except raku -h. Is there >> more helpful stuff somewhere in doc.raku.org? If so I could'nt find it. >> > > >> > > Thanks, >> > > Wolfgang >> > >> > Hi Wolfgang, >> > >> > This is a first attempt at doing what you want: I'm sure it can be >> > shortened. Since one of your requirements is doing a sort on filtered >> > values stored in an array, I abandoned use of the "-ne" one-liner >> > flag, using "-e" and "for lines()" instead. I also used grep instead >> > of smart-matching: >> > >> > perl6 -e 'my @i; for lines() {if .grep(/^WARN/) -> ($s) >> > {@i.push($s)};}; .say for @i.sort;' >> > >> > Note: the "-> ($s)" section where I store grepped matches comes from a >> > Jonathan Worthington answer found here (thanks Jonathan!): >> > >> > >> stackoverflow.com/questions/58982745/raku-one-line-expression-to-capture-group-from-string >> > >> > I certainly would be interested to learn if there's a phaser solution >> > to this problem (and I also have a sneaking suspicion that Supply >> > might be useful here... ). >> > >> > HTH, Bill. >> > > > -- > Fernando Santagata >
Re: NativeCall questions
Thanks for the information! Have a great weekend! Best regards, David Santiago Tobias Boege escreveu no dia sexta, 8/05/2020 à(s) 15:52: > > On Fri, 08 May 2020, David Santiago wrote: > > I also noticed that although my data string is defined as > > CArray[uint8], when i loop through the array, the values are signed > > ints: > > > > say $_ for $ed.data[0..10]; > > > > output: > > > > -98 > > There is an old open bug report about this: > https://github.com/Raku/old-issue-tracker/issues/5859 > > Best, > Tobias
Re: Raku -npe command line usage
raku -e'.say for lines() ==> grep(/^WARN/) ==> sort' sample.log is not very satisfying because for the "for" which breaks the flow. OTOH this raku -e'lines().grep(/^WARN/).sort».say' sample.log doesn't use the feed operator and this raku -e'lines() ==> grep(/^WARN/) ==> sort() ==> say()' sample.log outputs a list on one line, not each line on its own. This one works, but it feels awkward: raku -e'lines() ==> grep(/^WARN/) ==> sort() ==> reduce({$^a ~ "\n" ~ $^b}) ==> say()' sample.log On Fri, May 8, 2020 at 5:49 PM yary wrote: > All good ideas so far, in the "more than one way to do it" spirit, can use > "state" instead of "my", since state only initializes 1st time it's hit. > > raku -ne 'state @i;@i.push($_) if .starts-with(q[WARN]); END .say for > @i.sort' sample.log > > Or adapting Brad's answer with the feed operator for fun > > raku -e 'for lines() ==> grep /^WARN/ ==> sort() {.say}' sample.log > > Now, I didn't want to use 'map' in there, because of a habit of only using > 'map' when I want the return values. When looping for side-effects only, > like saying each value in a list, I want to use 'for'. UnFORtunately though > I cannot find anything as clean looking as > > raku -e 'lines() ==> grep /^WARN/ ==> sort() ==> map *.say' sample.log > > reading entirely L-to-R which does NOT use map... ideas? > > -y > > > On Fri, May 8, 2020 at 10:10 AM William Michels via perl6-users < > perl6-users@perl.org> wrote: > > > > On Fri, May 8, 2020 at 5:16 AM WFB wrote: > > > > > > Hi, > > > > > > I am trying to write an one-liner to go through all lines in a logfile > and look for an certain key word, store the line and sort them before > printing them out. > > > > > > My approach was: > > > raku -ne "BEGIN {my @i }; @i.push($_); if $_ ~~ /^WARN/; END { > @i.sort.say }" > > > That does not work because @i does not exist in the if clause. I tried > our @i as well with no luck. > > > > > > How can I store data that can be accessed in the END phaser? Or is > there another way to archive it? TIMTOWTDI^^ > > > > > > One hint I found was the variable $ and @ respectively. But those > variables are created for each line new... > > > > > > > > > I did not found a help or examples for -npe except raku -h. Is there > more helpful stuff somewhere in doc.raku.org? If so I could'nt find it. > > > > > > Thanks, > > > Wolfgang > > > > Hi Wolfgang, > > > > This is a first attempt at doing what you want: I'm sure it can be > > shortened. Since one of your requirements is doing a sort on filtered > > values stored in an array, I abandoned use of the "-ne" one-liner > > flag, using "-e" and "for lines()" instead. I also used grep instead > > of smart-matching: > > > > perl6 -e 'my @i; for lines() {if .grep(/^WARN/) -> ($s) > > {@i.push($s)};}; .say for @i.sort;' > > > > Note: the "-> ($s)" section where I store grepped matches comes from a > > Jonathan Worthington answer found here (thanks Jonathan!): > > > > > stackoverflow.com/questions/58982745/raku-one-line-expression-to-capture-group-from-string > > > > I certainly would be interested to learn if there's a phaser solution > > to this problem (and I also have a sneaking suspicion that Supply > > might be useful here... ). > > > > HTH, Bill. > -- Fernando Santagata
Re: NativeCall questions
On Fri, 08 May 2020, David Santiago wrote: > I also noticed that although my data string is defined as > CArray[uint8], when i loop through the array, the values are signed > ints: > > say $_ for $ed.data[0..10]; > > output: > > -98 There is an old open bug report about this: https://github.com/Raku/old-issue-tracker/issues/5859 Best, Tobias
Re: NativeCall questions
I also noticed that although my data string is defined as CArray[uint8], when i loop through the array, the values are signed ints: say $_ for $ed.data[0..10]; output: -98 -110 -109 -99 74 -109 -99 74 -105 -93 74 Is it possible to not "sign" them? Regards, David Santiago Curt Tilmes escreveu no dia sexta, 8/05/2020 à(s) 12:56: > > On Fri, May 8, 2020 at 8:49 AM David Santiago wrote: > > > EncodedData* ed = malloc(sizeof(EncodedData)); > > ed->data = encbuffer; > > ed->crc32 = crc32; > > return ed; > > You're returning a pointer to encbuffer -- make sure the storage for > that is kept around > somewhere. If it is passed in from Raku, you'll be fine as long as > you hold on to the > object on that side. Otherwise you might need to allocate/copy it to make > sure. > > > class EncodedData is repr('CStruct') { > > has CArray[uint8] $.data; > > has uint32 $.crc32; > > } > > That's fine, but CArray[uint8] is just a pointer -- it doesn't know > how long the array > it is pointing to is. It either needs a sentinel at the end (like the > Nul at the end of a > C string), or a separate field with a size to figure that out. > > > Don't know how many elements a C array returned from a library > > yep > > Curt
Re: Raku -npe command line usage
On Fri, May 8, 2020 at 5:16 AM WFB wrote: > > Hi, > > I am trying to write an one-liner to go through all lines in a logfile and > look for an certain key word, store the line and sort them before printing > them out. > > My approach was: > raku -ne "BEGIN {my @i }; @i.push($_); if $_ ~~ /^WARN/; END { @i.sort.say }" > That does not work because @i does not exist in the if clause. I tried our @i > as well with no luck. > > How can I store data that can be accessed in the END phaser? Or is there > another way to archive it? TIMTOWTDI^^ > > One hint I found was the variable $ and @ respectively. But those variables > are created for each line new... > > > I did not found a help or examples for -npe except raku -h. Is there more > helpful stuff somewhere in doc.raku.org? If so I could'nt find it. > > Thanks, > Wolfgang Hi Wolfgang, This is a first attempt at doing what you want: I'm sure it can be shortened. Since one of your requirements is doing a sort on filtered values stored in an array, I abandoned use of the "-ne" one-liner flag, using "-e" and "for lines()" instead. I also used grep instead of smart-matching: perl6 -e 'my @i; for lines() {if .grep(/^WARN/) -> ($s) {@i.push($s)};}; .say for @i.sort;' Note: the "-> ($s)" section where I store grepped matches comes from a Jonathan Worthington answer found here (thanks Jonathan!): stackoverflow.com/questions/58982745/raku-one-line-expression-to-capture-group-from-string I certainly would be interested to learn if there's a phaser solution to this problem (and I also have a sneaking suspicion that Supply might be useful here... ). HTH, Bill.
Re: Raku -npe command line usage
The 「@i」 is defined within the 「BEGIN」 block, so it is scoped to the 「BEGIN」 block. If you didn't want that, don't use a *block* with 「BEGIN」. BEGIN my @i; Also you wrote the 「if」 wrong. There shouldn't be a 「;」 before the 「if」. You also don't need to use 「$_ ~~ 」 with 「/^WARN/」 as that would automatically happen. @i.push($_) if /^WARN/; You probably also want the lines to be written each to to their own lines. So you probably want one of the following. @i.sort.map( *.say ) .say for @i.sort Again you don't need to use a block with 「END」 either. So together that would be: raku -ne 'BEGIN my @i; @i.push($_) if /^WARN/; END .say for @i.sort' --- That said, I wouldn't use -n in this case. raku -e 'lines.grep( /^WARN/ ).sort.map( *.say )' Currently regexes are a bit slow. You can use 「.starts-with」 instead to make it faster. raku -e 'lines.grep( *.starts-with(q[WARN]) ).sort.map( *.say )' (Note that 「 'abc' 」 is short for 「 q'abc' 」 which can also be written as 「 q[abc] 」. The latter is useful on the command line so that it doesn't interfere with the command processor quoting rules.) On Fri, May 8, 2020 at 7:16 AM WFB wrote: > Hi, > > I am trying to write an one-liner to go through all lines in a logfile and > look for an certain key word, store the line and sort them before printing > them out. > > My approach was: > raku -ne "BEGIN {my @i }; @i.push($_); if $_ ~~ /^WARN/; END { @i.sort.say > }" > That does not work because @i does not exist in the if clause. I tried our > @i as well with no luck. > > How can I store data that can be accessed in the END phaser? Or is there > another way to archive it? TIMTOWTDI^^ > > One hint I found was the variable $ and @ respectively. But those > variables are created for each line new... > > > I did not found a help or examples for -npe except raku -h. Is there more > helpful stuff somewhere in doc.raku.org? If so I could'nt find it. > > Thanks, > Wolfgang >
Re: NativeCall questions
On Fri, May 8, 2020 at 8:49 AM David Santiago wrote: > EncodedData* ed = malloc(sizeof(EncodedData)); > ed->data = encbuffer; > ed->crc32 = crc32; > return ed; You're returning a pointer to encbuffer -- make sure the storage for that is kept around somewhere. If it is passed in from Raku, you'll be fine as long as you hold on to the object on that side. Otherwise you might need to allocate/copy it to make sure. > class EncodedData is repr('CStruct') { > has CArray[uint8] $.data; > has uint32 $.crc32; > } That's fine, but CArray[uint8] is just a pointer -- it doesn't know how long the array it is pointing to is. It either needs a sentinel at the end (like the Nul at the end of a C string), or a separate field with a size to figure that out. > Don't know how many elements a C array returned from a library yep Curt
Re: NativeCall questions
Thanks for the help. > EncodedData *encode(unsigned char* data, size_t data_size) > and return > Also your struct and CStruct are defining the contents in the reverse > order. They must > match up exactly. > I did those two changes: """ EncodedData* ed = malloc(sizeof(EncodedData)); ed->data = encbuffer; ed->crc32 = crc32; return ed; """ And i also changed the CStruct [1] to: class EncodedData is repr('CStruct') { has CArray[uint8] $.data; has uint32 $.crc32; } I'm not getting a SIGSEGV anymore, however i'm now getting the following error when trying to "say $_ for $ed.data.list": Don't know how many elements a C array returned from a library in method elems at /usr/share/perl6/core/sources/8660F65A7B3492675BB3B2058DB30E411A4C4E54 (NativeCall::Types) line 223 in method list at /usr/share/perl6/core/sources/8660F65A7B3492675BB3B2058DB30E411A4C4E54 (NativeCall::Types) line 226 in sub MAIN at bin/uints.p6 line 15 in block at bin/uints.p6 line 3 I can access without problems $ed.crc32 [1] - if i change the data type to str i get the error: "String corruption detected: bad storage type" Best regards, David Santiago
Raku -npe command line usage
Hi, I am trying to write an one-liner to go through all lines in a logfile and look for an certain key word, store the line and sort them before printing them out. My approach was: raku -ne "BEGIN {my @i }; @i.push($_); if $_ ~~ /^WARN/; END { @i.sort.say }" That does not work because @i does not exist in the if clause. I tried our @i as well with no luck. How can I store data that can be accessed in the END phaser? Or is there another way to archive it? TIMTOWTDI^^ One hint I found was the variable $ and @ respectively. But those variables are created for each line new... I did not found a help or examples for -npe except raku -h. Is there more helpful stuff somewhere in doc.raku.org? If so I could'nt find it. Thanks, Wolfgang
Re: NativeCall questions
On Fri, May 8, 2020 at 6:44 AM David Santiago wrote: > > I'm porting some personal perl5 scripts to Raku, and one of those > scripts is using Inline::C. > [...] > Why? How do i fix it? I haven't tried all of this, but the first thing that leaps out is that repr('CStruct') is not a struct -- it is a pointer to a struct. Your 'return ed' will return the struct by value, not by reference/pointer. To return that, you need a signature like this: EncodedData *encode(unsigned char* data, size_t data_size) and return Also your struct and CStruct are defining the contents in the reverse order. They must match up exactly. > Also the read method from the IO::Handle returns a Buf. I would like > to pass it directly to my C function. Is there any change in the > C/raku code i should do? > The data field from class EncodedData is type "str". Should it be > CArray[uint8] instead? Str is good for things that are Nul-terminated and can be safely parsed as unicode strings. (I generally use Str instead of str even for NativeCall stuff.) Here you are passing in the size, though. You have to be careful using '.chars' to get the size in bytes. They might not be the same in all cases. I would recommend just passing it in as a 'Blob'. sub encode(Blob $data, size_t $size --> EncodedData) is native('lib/MyLib/libmylib.so') {*}; my $buf = "my string".encode; my $encoded = encode($buf, $buf.bytes); Using str in your CStruct for the return should be fine if the returned string is Nul-terminated and can be safely parsed. Otherwise define it as CArray[uint8]. Curt
Re: NativeCall questions
Hi David, the first thing that catches my eye is that your struct and the class have the members switched around, so you're already almost guaranteed to read a bogus pointer when trying to get the data. Also, please note that returning structs directly, or passing structs directly, as arguments is hairy business, you'll probably want to work with pointers instead, which either means your function has to malloc the EncodedData struct, or take a pointer to an already created one as an argument - you would then create the EncodedData on the raku side with a .new Whenever you declare a struct to be passed as argument or received as return value in NativeCall, you will get "TheStruct *" on the C side. Not sure if that's all it takes to fix this. Feel free to write back to the list. Hope to Help - Timo On 08/05/2020 12:44, David Santiago wrote: > Hello, > > I'm porting some personal perl5 scripts to Raku, and one of those > scripts is using Inline::C. > > The inline::c code would contain a function with the signature: > > AV* encode(unsigned char* data, size_t data_size) > > Description of the parameters on the original perl script: > data -> binary string (the value comes from read $FH) > data_size -> size in bytes of binary_string (the value comes from the > return of the read function) > > And it would return an array with two values (a binary string and its crc32): > > """ > SV* enc_string = newSVpv(buffer, 0); > SV* ret = sv_2mortal(newAV()); > av_push(ret, enc_string); > SV* hex_string = newSVpv(hex_number, 0); > av_push(ret, hex_string); > free(hex_number); > return ret; > """ > > > Now for using it in raku, i'm changing the return value to a struct: > typedef struct{ > unsigned char* data; > uint32_t crc32; > } EncodedData; > > So i changed the signature to: > EncodedData encode(unsigned char* data, size_t data_size) > > And i'm returning the struct: > """ > EncodedData ed; > ed.crc32 = crc32; > ed.data = encbuffer; > > return ed; > """ > > Create a shared lib gcc -shared -olibmylib.so mylib.c > > Now on my raku script i did: > """ > class EncodedData is repr('CStruct') { > has uint32 $.crc32; > has str $.data; > } > > sub MAIN() { > sub encode(str $data, size_t $size --> EncodedData) is > native('lib/MyLib/libmylib.so') {*}; > my EncodedData $ed = encode("this is my string that will be > encoded", "this is my string that will be encoded".chars ); > say $ed.crc32.base(16); > say $ed.data; > } > """ > However this isn't working. Everytime i access "$ed.data" I'm getting > the following error: > "fish: 'raku bin/uints.p6' terminated by signal SIGSEGV (Address > boundary error)" > > Why? How do i fix it? > > Also the read method from the IO::Handle returns a Buf. I would like > to pass it directly to my C function. Is there any change in the > C/raku code i should do? > The data field from class EncodedData is type "str". Should it be > CArray[uint8] instead? > > Best regards, > David Santiago
NativeCall questions
Hello, I'm porting some personal perl5 scripts to Raku, and one of those scripts is using Inline::C. The inline::c code would contain a function with the signature: AV* encode(unsigned char* data, size_t data_size) Description of the parameters on the original perl script: data -> binary string (the value comes from read $FH) data_size -> size in bytes of binary_string (the value comes from the return of the read function) And it would return an array with two values (a binary string and its crc32): """ SV* enc_string = newSVpv(buffer, 0); SV* ret = sv_2mortal(newAV()); av_push(ret, enc_string); SV* hex_string = newSVpv(hex_number, 0); av_push(ret, hex_string); free(hex_number); return ret; """ Now for using it in raku, i'm changing the return value to a struct: typedef struct{ unsigned char* data; uint32_t crc32; } EncodedData; So i changed the signature to: EncodedData encode(unsigned char* data, size_t data_size) And i'm returning the struct: """ EncodedData ed; ed.crc32 = crc32; ed.data = encbuffer; return ed; """ Create a shared lib gcc -shared -olibmylib.so mylib.c Now on my raku script i did: """ class EncodedData is repr('CStruct') { has uint32 $.crc32; has str $.data; } sub MAIN() { sub encode(str $data, size_t $size --> EncodedData) is native('lib/MyLib/libmylib.so') {*}; my EncodedData $ed = encode("this is my string that will be encoded", "this is my string that will be encoded".chars ); say $ed.crc32.base(16); say $ed.data; } """ However this isn't working. Everytime i access "$ed.data" I'm getting the following error: "fish: 'raku bin/uints.p6' terminated by signal SIGSEGV (Address boundary error)" Why? How do i fix it? Also the read method from the IO::Handle returns a Buf. I would like to pass it directly to my C function. Is there any change in the C/raku code i should do? The data field from class EncodedData is type "str". Should it be CArray[uint8] instead? Best regards, David Santiago