Re: Ping JJ: string literals

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 21:42, Paul Procacci wrote:

Sorry.  Not a WINAPI expert, nor do I want to be.  ;)

The $nSize variable looks fishy.  Can it ever contain a value that's <= 2?
If so, you're in for a surprise one day.  ;)

Bedtime.

~Paul



Hi Paul,

Great catch.  Thank you for the peer preview!

-T

I now looks like:

   if not $lpBuffer[ 0 ] == -1  {# -1 = 0xFF (it gets coersed) 
means nothing was returned

  loop (my $Index=0; $Index < $nSize  - 2 ; $Index += 2) {
 my byte $i = $lpBuffer[ $Index ] +| 0x00;
 if $i eq 0x00  { last; }
 $ErrorString ~= chr ( $i );
  }
   }


Re: Ping JJ: string literals

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 21:49, ToddAndMargo via perl6-users wrote:

On 2020-01-18 21:42, Paul Procacci wrote:

Sorry.  Not a WINAPI expert, nor do I want to be.  ;)


No Welcome to the Dar Side for you!!!

:-)


The $nSize variable looks fishy.  Can it ever contain a value that's 
<= 2?


The buffer always has some size to it.  Maybe not.

This is is what it looks like when yuo send it a
bogus error to decode

Oh poop, now I have to troubleshoot this:

K:\Windows\NtUtil>perl6 -I. -e "use lib '.'; use WinErr 
:WinFormatMessage; say WinFormatMessage( 0xF789, True );"


chr codepoint cannot be negative
   in sub WinFormatMessage at K:\Windows\NtUtil\WinErr.pm6 (WinErr) line 
118

   in block  at -e line 1

I does not like 0x as the first word.

Life in the fast lane.

:-)



Go it fixed.

$nSize starts as the size of the buffer, so
it will be 1024 is nothing gets returned.

A bad error code

K:\Windows\NtUtil>perl6 -I. -e "use lib '.'; use WinErr 
:WinFormatMessage; say WinFormatMessage( 0xF789, True );"

WinFormatMessage: Debug:
   WinGetLastError  317
   Error Number 63369
   nSize1024
   RtnCode  0
   Error String Characters  14
   ErrorString  


Bad Error Code



A good error code:

K:\Windows\NtUtil>perl6 -I. -e "use lib '.'; use WinErr 
:WinFormatMessage; say WinFormatMessage( 0x789, True );"

WinFormatMessage: Debug:
   WinGetLastError  0
   Error Number 1929
   nSize1024
   RtnCode  41
   Error String Characters  39
   ErrorString  


The group element could not be removed.


Re: Ping JJ: string literals

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 21:42, Paul Procacci wrote:

Sorry.  Not a WINAPI expert, nor do I want to be.  ;)


No Welcome to the Dar Side for you!!!

:-)



The $nSize variable looks fishy.  Can it ever contain a value that's <= 2?


The buffer always has some size to it.  Maybe not.

This is is what it looks like when yuo send it a
bogus error to decode

Oh poop, now I have to troubleshoot this:

K:\Windows\NtUtil>perl6 -I. -e "use lib '.'; use WinErr 
:WinFormatMessage; say WinFormatMessage( 0xF789, True );"


chr codepoint cannot be negative
  in sub WinFormatMessage at K:\Windows\NtUtil\WinErr.pm6 (WinErr) line 118
  in block  at -e line 1

I does not like 0x as the first word.

Life in the fast lane.

:-)


Re: Ping JJ: string literals

2020-01-18 Thread Paul Procacci
Sorry.  Not a WINAPI expert, nor do I want to be.  ;)

The $nSize variable looks fishy.  Can it ever contain a value that's <= 2?
If so, you're in for a surprise one day.  ;)

Bedtime.

~Paul

On Sun, Jan 19, 2020 at 12:28 AM ToddAndMargo via perl6-users <
perl6-us...@perl.org> wrote:

> On 2020-01-18 21:20, Paul Procacci wrote:
> > Perfect.  Obviously didn't know that.  My assumption that only the first
> > byte gets checked was obviously wrong.
> >
> > Thanks gents.
>
>
> This is the way I dig out the ascii characters
> from the word array. $nSize comes back from
> function call.
>
> loop (my $Index=0; $Index < $nSize  - 2 ; $Index += 2) {
>my $i = chr( $lpBuffer[ $Index ] );
>if $i eq chr(0)  { last; }
>$ErrorString ~= $i;
> }
>
> The `$Index += 2` skips over the second byte in the
> WORD array.
>
> So far, WinAPI call have always sent me back
> ascii characters in the first byte and a zero
> in the second.
>
> 84 0 104 0 101 0 32 0 103 0 114 0 111 0 117 0 112 0 32 0 101 0 108 0 101
> 0 109 0 101 0 110 0 116 0 32 0 99 0 111 0 117 0 108 0 100 0 32 0 110 0
> 111 0 116 0 32 0 98 0 101 0 32 0 114 0 101 0 109 0 111 0 118 0 101 0 100
> 0 46 0 13 0 10 0 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
> -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
> -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
>


-- 
__

:(){ :|:& };:


Re: Ping JJ: string literals

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 21:20, Paul Procacci wrote:
Perfect.  Obviously didn't know that.  My assumption that only the first 
byte gets checked was obviously wrong.


Thanks gents.



This is the way I dig out the ascii characters
from the word array. $nSize comes back from
function call.

   loop (my $Index=0; $Index < $nSize  - 2 ; $Index += 2) {
  my $i = chr( $lpBuffer[ $Index ] );
  if $i eq chr(0)  { last; }
  $ErrorString ~= $i;
   }

The `$Index += 2` skips over the second byte in the
WORD array.

So far, WinAPI call have always sent me back
ascii characters in the first byte and a zero
in the second.

84 0 104 0 101 0 32 0 103 0 114 0 111 0 117 0 112 0 32 0 101 0 108 0 101 
0 109 0 101 0 110 0 116 0 32 0 99 0 111 0 117 0 108 0 100 0 32 0 110 0 
111 0 116 0 32 0 98 0 101 0 32 0 114 0 101 0 109 0 111 0 118 0 101 0 100 
0 46 0 13 0 10 0 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1


Re: Ping JJ: string literals

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 21:04, ToddAndMargo via perl6-users wrote:

I changed the initialization of the buffer from
0x00 to 0xFF to make the double nul at the end a
bit more obvious:

 # my BYTES  $lpBuffer = CArray[BYTE].new( 0 xx $nSize );
 my BYTES  $lpBuffer = CArray[BYTE].new( 0xFF xx $nSize );


84 0 104 0 101 0 32 0 103 0 114 0 111 0 117 0 112 0 32 0 101 0 108 0 101 
0 109 0 101 0 110 0 116 0 32 0 99 0 111 0 117 0 108 0 100 0 32 0 110 0 
111 0 116 0 32 0 98 0 101 0 32 0 114 0 101 0 109 0 111 0 118 0 101 0 100 
0 46 0 13 0 10 0 0 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 ...


Re: Ping JJ: string literals

2020-01-18 Thread Paul Procacci
Perfect.  Obviously didn't know that.  My assumption that only the first
byte gets checked was obviously wrong.

Thanks gents.

On Sun, Jan 19, 2020 at 12:12 AM yary  wrote:

> In UTF-16 every character is 16 bits, so all 8 bits of zeros tells you is
> that it's possibly a big-endian ascii character or a little-endian
> non-ascii character at a position divisible by 256. All zeros U+ is
> unicode NULL, which the windows UTF-16 C convention uses to terminate the
> string.
> -y
>
>
> On Sat, Jan 18, 2020 at 9:04 PM ToddAndMargo via perl6-users <
> perl6-us...@perl.org> wrote:
>
>> On 2020-01-18 20:05, Paul Procacci wrote:
>> >  >> I also found out the
>> >  >> hard wasy the UTF16 strings need to be terminated with
>> >  >> a double nul (0x).
>> >
>> > Not to doubt you (I don't do anything in UTF-16), but can you show an
>> > example of this?
>> > I would have thought a single NULL character is enough.
>> >
>> > The 1st byte of a Unicode character determines whether or not it's
>> ascii
>> > or not and I wouldn't think when encountering the first null, any
>> > reasonable utf-16 interpretation would consume more than just that 1st
>> byte.
>>
>> Hi Paul,
>>
>> My dealings with UTF16 are dealing with Win API
>> calls to the registry.
>>
>> This is from my work in progress doc on NativeCall
>> and WinAPI:
>>
>>  Note: a UTF16 C string is “little-endian”
>>meaning “ABC” is represented as
>>0x4200 (A), 0X4300 (B), 0X4400 (C), 0x (nul)
>>
>> The following is a call to:
>>
>>
>> https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessagew
>>
>>   DWORD FormatMessageW(
>>   DWORD   dwFlags,  # bitwise OR
>> FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
>> FORMAT_MESSAGE_IGNORE_INSERTS
>>   LPCVOID lpSource, # NULL.  The location of the message
>> definition. The type of this parameter depends upon the settings in the
>> dwFlags parameter.
>>   DWORD   dwMessageId,  # the error message number ($ErrorNumber)
>>   DWORD   dwLanguageId, # 0 for system's language
>>   LPTSTR  lpBuffer, # the return string, give it 1024
>>   DWORD   nSize,# 0  nubmer of bytes in the return
>>   va_list *Arguments# NULL
>>   );
>>
>>
>> I have removed the comment from the call that prints out
>> the raw returned data.  It looks like this:
>>
>> 
>> K:\Windows\NtUtil>perl6 -I. -e "use lib '.'; use WinErr
>> :WinFormatMessage; say WinFormatMessage( 0x789, True );"
>>
>> 84 0 104 0 101 0 32 0 103 0 114 0 111 0 117 0 112 0 32 0 101 0 108 0 101
>> 0 109 0 101 0 110 0 116 0 32 0 99 0 111 0 117 0 108 0 100 0 32 0 110 0
>> 111 0 116 0 32 0 98 0 101 0 32 0 114 0 101 0 109 0 111 0 118 0 101 0 100
>> 0 46 0 13 0 10 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 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 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 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 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 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 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 0 0 0 0 0
>>
>> WinFormatMessage: Debug:
>> WinGetLastError  0
>> Error Number 1929
>> nSize1024
>> RtnCode  41
>> Error String Characters  39
>> ErrorString  
>>
>> 

Re: Ping JJ: string literals

2020-01-18 Thread yary
In UTF-16 every character is 16 bits, so all 8 bits of zeros tells you is
that it's possibly a big-endian ascii character or a little-endian
non-ascii character at a position divisible by 256. All zeros U+ is
unicode NULL, which the windows UTF-16 C convention uses to terminate the
string.
-y


On Sat, Jan 18, 2020 at 9:04 PM ToddAndMargo via perl6-users <
perl6-us...@perl.org> wrote:

> On 2020-01-18 20:05, Paul Procacci wrote:
> >  >> I also found out the
> >  >> hard wasy the UTF16 strings need to be terminated with
> >  >> a double nul (0x).
> >
> > Not to doubt you (I don't do anything in UTF-16), but can you show an
> > example of this?
> > I would have thought a single NULL character is enough.
> >
> > The 1st byte of a Unicode character determines whether or not it's ascii
> > or not and I wouldn't think when encountering the first null, any
> > reasonable utf-16 interpretation would consume more than just that 1st
> byte.
>
> Hi Paul,
>
> My dealings with UTF16 are dealing with Win API
> calls to the registry.
>
> This is from my work in progress doc on NativeCall
> and WinAPI:
>
>  Note: a UTF16 C string is “little-endian”
>meaning “ABC” is represented as
>0x4200 (A), 0X4300 (B), 0X4400 (C), 0x (nul)
>
> The following is a call to:
>
>
> https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessagew
>
>   DWORD FormatMessageW(
>   DWORD   dwFlags,  # bitwise OR
> FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
> FORMAT_MESSAGE_IGNORE_INSERTS
>   LPCVOID lpSource, # NULL.  The location of the message
> definition. The type of this parameter depends upon the settings in the
> dwFlags parameter.
>   DWORD   dwMessageId,  # the error message number ($ErrorNumber)
>   DWORD   dwLanguageId, # 0 for system's language
>   LPTSTR  lpBuffer, # the return string, give it 1024
>   DWORD   nSize,# 0  nubmer of bytes in the return
>   va_list *Arguments# NULL
>   );
>
>
> I have removed the comment from the call that prints out
> the raw returned data.  It looks like this:
>
> 
> K:\Windows\NtUtil>perl6 -I. -e "use lib '.'; use WinErr
> :WinFormatMessage; say WinFormatMessage( 0x789, True );"
>
> 84 0 104 0 101 0 32 0 103 0 114 0 111 0 117 0 112 0 32 0 101 0 108 0 101
> 0 109 0 101 0 110 0 116 0 32 0 99 0 111 0 117 0 108 0 100 0 32 0 110 0
> 111 0 116 0 32 0 98 0 101 0 32 0 114 0 101 0 109 0 111 0 118 0 101 0 100
> 0 46 0 13 0 10 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 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 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 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 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 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 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 0 0 0 0 0
>
> WinFormatMessage: Debug:
> WinGetLastError  0
> Error Number 1929
> nSize1024
> RtnCode  41
> Error String Characters  39
> ErrorString  
>
> The group element could not be removed.
> 
>
>
> Note that the following UTF16 code is little endian and
>
> 84 0 104 0 101 0 32 0 103 0 114 0 111 0 117 0 112 0 32 0 101 0 108 0 101
> 0 109 0 101 0 110 0 116 0 32 0 99 0 111 0 117 0 108 0 100 0 32 0 110 0
> 111 0 116 0 32 0 98 0 101 0 32 0 

Re: Ping JJ: string literals

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 20:05, Paul Procacci wrote:

 >> I also found out the
 >> hard wasy the UTF16 strings need to be terminated with
 >> a double nul (0x).

Not to doubt you (I don't do anything in UTF-16), but can you show an 
example of this?

I would have thought a single NULL character is enough.

The 1st byte of a Unicode character determines whether or not it's ascii 
or not and I wouldn't think when encountering the first null, any 
reasonable utf-16 interpretation would consume more than just that 1st byte.


Hi Paul,

My dealings with UTF16 are dealing with Win API
calls to the registry.

This is from my work in progress doc on NativeCall
and WinAPI:

Note: a UTF16 C string is “little-endian”
  meaning “ABC” is represented as
  0x4200 (A), 0X4300 (B), 0X4400 (C), 0x (nul)

The following is a call to:

https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessagew

 DWORD FormatMessageW(
 DWORD   dwFlags,  # bitwise OR 
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | 
FORMAT_MESSAGE_IGNORE_INSERTS
 LPCVOID lpSource, # NULL.  The location of the message 
definition. The type of this parameter depends upon the settings in the 
dwFlags parameter.

 DWORD   dwMessageId,  # the error message number ($ErrorNumber)
 DWORD   dwLanguageId, # 0 for system's language
 LPTSTR  lpBuffer, # the return string, give it 1024
 DWORD   nSize,# 0  nubmer of bytes in the return
 va_list *Arguments# NULL
 );


I have removed the comment from the call that prints out
the raw returned data.  It looks like this:


K:\Windows\NtUtil>perl6 -I. -e "use lib '.'; use WinErr 
:WinFormatMessage; say WinFormatMessage( 0x789, True );"


84 0 104 0 101 0 32 0 103 0 114 0 111 0 117 0 112 0 32 0 101 0 108 0 101 
0 109 0 101 0 110 0 116 0 32 0 99 0 111 0 117 0 108 0 100 0 32 0 110 0 
111 0 116 0 32 0 98 0 101 0 32 0 114 0 101 0 109 0 111 0 118 0 101 0 100 
0 46 0 13 0 10 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 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 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 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 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 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 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 0 0 0 0 0


WinFormatMessage: Debug:
   WinGetLastError  0
   Error Number 1929
   nSize1024
   RtnCode  41
   Error String Characters  39
   ErrorString  

The group element could not be removed.



Note that the following UTF16 code is little endian and

84 0 104 0 101 0 32 0 103 0 114 0 111 0 117 0 112 0 32 0 101 0 108 0 101 
0 109 0 101 0 110 0 116 0 32 0 99 0 111 0 117 0 108 0 100 0 32 0 110 0 
111 0 116 0 32 0 98 0 101 0 32 0 114 0 101 0 109 0 111 0 118 0 101 0 100 
0 46 0 13 0 10 0 0 0


corresponds to:

"The group element could not be removed", which
is error 0x789.

And you can see why you need the double nul.

The carriage return and line feed (13 0 10 0) were
fun to deal with.

The code yourself is rather long winded.  If you
would like to run the code yourself, I can post
it to vpaste.net along with its companion module(s).

-T


Re: Ping JJ: string literals

2020-01-18 Thread Paul Procacci
>> I also found out the
>> hard wasy the UTF16 strings need to be terminated with
>> a double nul (0x).

Not to doubt you (I don't do anything in UTF-16), but can you show an
example of this?
I would have thought a single NULL character is enough.

The 1st byte of a Unicode character determines whether or not it's ascii or
not and I wouldn't think when encountering the first null, any reasonable
utf-16 interpretation would consume more than just that 1st byte.





On Sat, Jan 18, 2020 at 10:14 PM ToddAndMargo via perl6-users <
perl6-us...@perl.org> wrote:

> On 2020-01-18 04:55, Tobias Boege wrote:
> > BUT the terminating NUL character is not inserted by NativeCall and it
> > isn't inserted by 
>
>
> Hi Tobias,
>
> I found this out the hard way.  I also found out the
> hard wasy the UTF16 strings need to be terminated with
> a double nul (0x).
>
> -T
>


-- 
__

:(){ :|:& };:


Re: Ping JJ: string literals

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 04:55, Tobias Boege wrote:

BUT the terminating NUL character is not inserted by NativeCall and it
isn't inserted by 



Hi Tobias,

I found this out the hard way.  I also found out the
hard wasy the UTF16 strings need to be terminated with
a double nul (0x).

-T


Re: Using raku/perl6 as unix "cat"....

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 17:54, yary wrote:
"while" is the wrong looping construct for going over file lines, and 
that's across a great many computer languages. It will stop when it 
encounters a false line- typically an empty line or '0'


Try "for"

-y



Hi William,

I don't know if this will help you, but
I have a sitution when I read thousands of
lines into a string.  The lines have
CR/LF in them. To read through the string,
line by line, I use Yary's suggestion with the
following addition:

for $x.lines -> $Line { magic stuff ; }

-T


Re: Ping JJ: string literals

2020-01-18 Thread ToddAndMargo via perl6-users



Would you be so kind to post this as an issue in the documentation, so 
we can pick up on it?


Thanks!

JJ


Would you mind posting back the link to it, so I can
get on the following list?


Re: definition confusion of + and +^

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 15:59, Elizabeth Mattijsen wrote:



s/he/it/


The idea that no gentleman ever swears is all wrong.
He can swear and still be a gentleman, if he does
it in a nice and benevolent and affectionate way.
--Mark Twain  - Private and Public Morals speech, 1906

:-)


Re: Using raku/perl6 as unix "cat"....

2020-01-18 Thread yary
"while" is the wrong looping construct for going over file lines, and
that's across a great many computer languages. It will stop when it
encounters a false line- typically an empty line or '0'

Try "for"

-y


On Sat, Jan 18, 2020 at 4:45 PM William Michels 
wrote:

> Hello All,
>
> I've been reviewing literature that discusses using raku/perl6 as a
> replacement for common unix utilities. One important unix utility is
> "cat". I looked at docs/blogs and found a recommendation to use "$*IN"
> along with "slurp" (references at bottom). Using a seven-line test
> file "testthis_abc_def.txt" below (1), the recommended "slurp" code
> works as expected (2).
>
> However, another recommendation to use "$*IN" along with the "get"
> method fails when a blank line is encountered, only returning
> truncated output (3). I tried correcting truncated output seen with
> "get" by playing with the command-line arguments "-ne" (4) and "-pe"
> (5), but only ended up mangling output even further.
>
> Can "get" be used in when writing raku/perl6 replacement code for "cat"?
>
> Any advice appreciated,
>
> Bill.
>
>
> [1]mydir$ cat testthis_abc_def.txt
> a
> b
> c
>
> d
> e
> f
> [2]mydir$ perl6 -e 'say $*IN.slurp;' < testthis_abc_def.txt
> a
> b
> c
>
> d
> e
> f
>
> [3]mydir$ perl6 -e '.say while $_ = $*IN.get;' < testthis_abc_def.txt
> a
> b
> c
> [4]mydir$ perl6 -ne '.say while $_ = $*IN.get;' < testthis_abc_def.txt
> b
> c
> e
> f
> [5]mydir$ perl6 -pe '.say while $_ = $*IN.get;' < testthis_abc_def.txt
> b
> c
>
> e
> f
> (Mu)
> [6]mydir$
>
>
> REFERENCES:
> 1. https://docs.raku.org/routine/slurp
> 2. https://docs.raku.org/routine/get
> 3. https://andrewshitov.com/2019/09/09/the-cat-utility-written-in-perl-6/
> 4.
> https://stackoverflow.com/questions/52597984/catching-exception-of-a-shell-command-in-perl-6
>


Re: definition confusion of + and +^

2020-01-18 Thread ToddAndMargo via perl6-users

Hi All,

Thank you all for the wonderful help on this.

What I am still confused about is how to
read these silly definition lines:

   multi sub infix:<+>($a, $b --> Numeric:D)
   multi sub infix:<+^>($a, $b --> Int:D)

How exactly does the above tell me to do this?

  $c = $a +  $b
  $c = $a +^ $b

I figured I'd start with addition and work my
way up.

Many thanks,
-T


Re: my keeper on bitwise operations

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 16:26, Elizabeth Mattijsen wrote:

On 19 Jan 2020, at 01:15, ToddAndMargo via perl6-users  
wrote:
alias p5='perl6 -E'


s/perl6/perl/




Great catch.  Thank you!

Perl: bitwise operators:

alias p5='perl -E'
alias p6='perl6 -e'




--
~~
Computers are like air conditioners.
They malfunction when you open windows
~~


Using raku/perl6 as unix "cat"....

2020-01-18 Thread William Michels via perl6-users
Hello All,

I've been reviewing literature that discusses using raku/perl6 as a
replacement for common unix utilities. One important unix utility is
"cat". I looked at docs/blogs and found a recommendation to use "$*IN"
along with "slurp" (references at bottom). Using a seven-line test
file "testthis_abc_def.txt" below (1), the recommended "slurp" code
works as expected (2).

However, another recommendation to use "$*IN" along with the "get"
method fails when a blank line is encountered, only returning
truncated output (3). I tried correcting truncated output seen with
"get" by playing with the command-line arguments "-ne" (4) and "-pe"
(5), but only ended up mangling output even further.

Can "get" be used in when writing raku/perl6 replacement code for "cat"?

Any advice appreciated,

Bill.


[1]mydir$ cat testthis_abc_def.txt
a
b
c

d
e
f
[2]mydir$ perl6 -e 'say $*IN.slurp;' < testthis_abc_def.txt
a
b
c

d
e
f

[3]mydir$ perl6 -e '.say while $_ = $*IN.get;' < testthis_abc_def.txt
a
b
c
[4]mydir$ perl6 -ne '.say while $_ = $*IN.get;' < testthis_abc_def.txt
b
c
e
f
[5]mydir$ perl6 -pe '.say while $_ = $*IN.get;' < testthis_abc_def.txt
b
c

e
f
(Mu)
[6]mydir$


REFERENCES:
1. https://docs.raku.org/routine/slurp
2. https://docs.raku.org/routine/get
3. https://andrewshitov.com/2019/09/09/the-cat-utility-written-in-perl-6/
4. 
https://stackoverflow.com/questions/52597984/catching-exception-of-a-shell-command-in-perl-6


Re: my keeper on bitwise operations

2020-01-18 Thread Elizabeth Mattijsen
> On 19 Jan 2020, at 01:15, ToddAndMargo via perl6-users  
> wrote:
> alias p5='perl6 -E'

s/perl6/perl/


my keeper on bitwise operations

2020-01-18 Thread ToddAndMargo via perl6-users

Hi All,

My keeper on bitwise operations:

-T



Perl: bitwise operators:

alias p5='perl6 -E'
alias p6='perl6 -e'


Shift Left and OR:
$ p6 'my Buf $x=Buf.new(0xAE,0x5D,0x5C,0x72);
  my int32 $i=$x[3] +< 0x18  +|  $x[2] +< 0x10  +|  $x[1] +< 
0x08  +|  $x[0];

  say $x; say $i.base(0x10);'

  Buf:0x
  725C5DAE


Bitwise += / ~=:  Put and "=" after the bitwise operator:

$ p6 'my int32 $i=0x5DAE; say $i.base(0x10); $i +<= 0x01; say 
$i.base(0x10);'

5DAE
BB5C

$ p6 'my $v = 0b0010; $v +|= 0b00010001; say $v;'
49

$ p6 'my $v = 0b0010; $v +|= 0b0001; say $v;'
48


Bitwise AND:
$ p6 'my $v = 32 +& 16; say $v;'
0

$ p5 'my $v = 32 & 16; say $v;'
0


Bitwise OR (note +|= example):
$ p5 'my $v = 32 | 16; say $v;'
48

$ p6 'my $v = 32 +| 16; say $v;'
48

$ p6 'my $v = 0b0010; $v +|= 0b00010001; say $v;'
49

$ p6 'my $v = 0b0010; $v +|= 0b0001; say $v;'
48


Bitwise shift left:
$ p6 'my $v = 0b0100 +< 2; say $v;'
16

$ p5 'my $v = 0b0100 << 3; say $v;'
32



Bitwise shift right:
$ p5 'my $v = 0b00010100 >> 3; say $v;'
32

$ p6 'my $v = 0b00110100 +> 3; say $v;'
6


Bitwise XOR:
$ p6 'my $v = 0b00101101 ^ 0b1001; say $v;'
36

$ p6 'my $v = 0b1101 +^ 0b1001; say $v;'
4

$ p6 'my uint8 $x = infix:<+^>( 0b1000_1010, 0b1010_0110 ); say 
"00", $x.base(2);'

00101100



Bitwise NOT (Ones Complement or flip the bits):
$ p6 'my uint8 $x=0b1010_0110; my uint8 $y = +^$x; my uint8 $z = $y 
+ 1;

  say $x.base(2); say "0", $y.base(2); say "0", $z.base(2);'
10100110  # original
01011001  # one's complement
01011010  # two's complement

   $ p6 'my uint8 $x= 0b1000_1010 +^ 0b1010_0110; say "00", $x.base(2);'
   00101100



Bitwise "IN" or Pattern Test (Does y exist in x):
$ p5 'my $x = 0b1001; my $y = 0b1000; say qw(false true)[($x & $y) 
== $y]'

true

$ p5 'my $x = 0b1001; my $y = 0b0100; say qw(false true)[($x & $y) 
== $y]'

false

$ p6 'my $x=0b1001; my $y=0b0101; my $z=$x +& $y; say so $y == $z;'
False

$ p6 'my $x=0b1001; my $y=0b1001; my $z=$x +& $y; say so $y == $z;'
True


Re: definition confusion of + and +^

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 15:59, Elizabeth Mattijsen wrote:

infix: foo + bar
prefix:+foo
postfix:   foo++
circumfix: [foo]
postcircumfix: foo[bar]


Hi Liz,

You are still putting the cart before the horse.

This is the step you jumped over:

   An "infix" is a term that  ...

You missed defining the terms.

Thank you anyway for trying to help.

-T


Re: definition confusion of + and +^

2020-01-18 Thread Elizabeth Mattijsen
> On 19 Jan 2020, at 00:24, ToddAndMargo via perl6-users  
> wrote:
> Wonderful so far.  But then he DOES not describe what
> "infix, prefix, postfix, circumfix, postcircumfix"
> arfe/means before jumping into details.  This is bad
> form in technical writing.

s/he/it/

> Again, wonderful so far.  But then he DOES not describe
> what  "infix, prefix, postfix, circumfix, postcircumfix"
> are/means before jumping into details.  This is also
> bad form in technical writing.

s/he/it/

> You meed to start at the simple and move methodically
> to the complex, especially when dealing with unicorn
> words that a specific to a topic.

infix: foo + bar
prefix:+foo
postfix:   foo++
circumfix: [foo]
postcircumfix: foo[bar]

Re: definition confusion of + and +^

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 13:16, Brad Gilbert wrote:


Note that Int:D does NOT do any coercions.

Int:D() does do coercions.

Specifically Int:D() is short for Int:D(Any). Which means it coerces 
from Any to Int, and the result must be defined.


Does the same apply to UInt:D and UInt:D()?


Re: definition confusion of + and +^

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 13:16, Curt Tilmes wrote:



On Sat, Jan 18, 2020, 3:39 PM ToddAndMargo via perl6-users 
mailto:perl6-us...@perl.org>> wrote:



4)  infix:<+> means you can call it as a sub that
      gives you back the wrong answer.

          $c = +($a, $b)
          $c = +^($a, $b)


You left off the infix:<> part of the sub's name.



I totally misunderstood what it meant.

So, do I still get a participation trophy?

:'(

-T


Re: definition confusion of + and +^

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 13:16, Brad Gilbert wrote:

Most operators in Raku are subroutines.

     1 + 2
     infix:<+>( 1, 2 )

     -1
     prefix:<->( 1 )


My mistake was thinking `infix:<+>` meqan to put the `+`
before the `)`





Note that Int:D does NOT do any coercions.

Int:D() does do coercions.

Specifically Int:D() is short for Int:D(Any). Which means it coerces 
from Any to Int, and the result must be defined.



Thank you for that.  I always waited for
the text to tell me that.


Re: definition confusion of + and +^

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 13:10, Veesh Goldman wrote:

Hi Todd,
I would suggest reading https://docs.raku.org/language/optut.


This one starts out with:

Operators are declared by using the sub keyword followed
by prefix, infix, postfix, circumfix, or postcircumfix;
then a colon and the operator name in a quote construct.
For (post-)circumfix operators separate the two parts
by white space.

Wonderful so far.  But then he DOES not describe what
"infix, prefix, postfix, circumfix, postcircumfix"
arfe/means before jumping into details.  This is bad
form in technical writing.



For a slightly more thorough read 
https://docs.raku.org/language/functions#Defining_operators.


That one starts out with:

 Operators are just subroutines with funny names. The
 funny names are composed of the category name (infix,
 prefix, postfix, circumfix, postcircumfix), followed
 by a colon, and a list of the operator name or names
 (two components in the case of circumfix and
 postcircumfix).

Again, wonderful so far.  But then he DOES not describe
what  "infix, prefix, postfix, circumfix, postcircumfix"
are/means before jumping into details.  This is also
bad form in technical writing.

You meed to start at the simple and move methodically
to the complex, especially when dealing with unicorn
words that a specific to a topic.

So poop!  Both links went flying right over my head.
The documentation will eventually improve.

:'(

-T


Re: problems with xor

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 13:25, Kevin Pye wrote:
As has been explained quite explicitly twice already, you call it as a 
sub by using the full explicit name of the subroutine:


$z = infix:<+^>($x, $y)


Hi Kevin,

My mistake was thinking "infix" was part of
the description of how to write the sub,
not acutally part of the sub's name.

I though `infix:<+^>` meant to put `+`
in front of the `(`.

:'(

-T


Re: definition confusion of + and +^

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 13:11, Marcel Timmerman wrote:


    my $a=2; my $b=3; my $c = +($a, $b)


Here is the mistake that + in front of a list means (...).elems (also 
used as a prefix, not infix), so there are 2 items in the list which is 
true. So '+(1,2,3)' returns 3 and '+(^10)' is 10 and '+(5..10)' returns 6

To do it right one can call 'infix:<+>(2, 3)' which returns 5.


Hi Marcel,

My mistake was thinking the "infix" was a description of
a sub, not actually part of the name:

my $a=0b10; my $b=0b11; my $c = infix:<+>($a, $b); say $c.base(2);
101

The word "infix" is on eof those unicorn word that
has no meaning to me.  I need to change that.



But the easy way is of course '2 + 3'.



1+  Oh no fooling!


    2

 And a participation trophy for the wrong answer.

    my $a=2; my $b=3; my $c = +^($a, $b)
    -3


Here you are using it as a prefix too, which means bitwise negation on 
anything what follows. The definition however is an infix so us it as 
'infix:<+^>(0b101, 0b010)' which returns 7. However it is easier to 
write '0b101 +^ 0b010' or the XOR of two numbers.


2+



See also: https://docs.raku.org/routine/+ and 
https://docs.raku.org/routine/+$CIRCUMFLEX_ACCENT


Same mistake again.  Dang!  At least I am
consistent.

And Double Dang!  I guess I won't be seeing my
participation trophy any time soon.

:'(

Thank you for the excellent explanation/technical writing!

-T


Re: problems with xor

2020-01-18 Thread Kevin Pye
As has been explained quite explicitly twice already, you call it as a sub
by using the full explicit name of the subroutine:

$z = infix:<+^>($x, $y)



On Sun, 19 Jan 2020 at 07:22, ToddAndMargo via perl6-users <
perl6-us...@perl.org> wrote:

> On 2020-01-18 06:09, Tobias Boege wrote:
> > On Fri, 17 Jan 2020, ToddAndMargo via perl6-users wrote:
> >> Hi All,
> >>
> >> https://docs.raku.org/routine/+$CIRCUMFLEX_ACCENT
> >>
> >> (Operators) infix +^§
> >>
> >> multi sub infix:<+^>($a, $b --> Int:D)
> >>
> >> Integer bitwise XOR operator: Coerces both arguments to Int and does a
> >> bitwise XOR (exclusive OR) operation.
> >>
> >>
> >> $ p6 'my uint8 $x=0b0101_0111; my uint8 $y = 0b_; my uint8 $z =
> >> +^($x, $y ); say "0", $x.base(2); say "", $y.base(2); say
> $z.base(2);'
> >>
> >> 01010111
> >> 
> >> 1101
> >>
> >>
> >> XOR
> >> A  B   A xor B
> >> 0  0  0
> >> 1  0  1
> >> 0  1  1
> >> 1  1  0
> >>
> >> That s not what I am seeing above.
> >>
> >> What am I doing wrong this time?
> >>
> >> And who set the high bit making $z negative?
> >>
> >
> > As was already mentioned, if you want to use the :<+^> operator,
> > you have to either call it by its full name as a sub:
> >
> >:<+^>($x, $y)
> >
> > or you have to use it according to its syntax category, as an infix:
> >
> >$x +^ $y
> >
> > When you write +^($x,$y), its cousin :<+^> is called instead,
> > because now you use +^ as a prefix operator. That one performs bitwise
> > negation on its argument coerced to Int, and since you pass it a list
> > of length two, you actually evaluate +^2. And that's how you get the
> > high bit and a value of -3.
> >
> > Regards,
> > Tobias
> >
>
> Hi Tobias,
>
> This works perfectly using the syntax $a = $b +^ $c
>
> p6 'my uint8 $x=0b0101_0111; my uint8 $y = 0b_; my uint8 $z = $x
> +^ $y; say "0", $x.base(2); say "", $y.base(2); say "0",$z.base(2);'
>
> 01010111# $x
> # $y
> 01011000# z = x xor y
>
>
> But what is now confusing me is $c = +^( $a, $b )
>
> p6 'my uint8 $x=0b0101_0111; my uint8 $y = 0b_; my uint8 $z =
> +^($x, $y); say "0", $x.base(2); say "", $y.base(2); say $z.base(2);'
>
> 01010111# $x
> # $y
> 1101# z is not  x xor y
>
> Which is clearly not correct.  The manual states:
>
>Integer bitwise XOR operator: Coerces both
>arguments to Int and does a bitwise XOR
>(exclusive OR) operation.
>
> In my example run line, I purposefully left the
> high bit off to keep overly helpful Raku from thinking
> I had a negative number when it annoyingly overrules
> my choice of native type.  (Ordinarily I like this
> feature, except when doing bitwise operations, I
> wish I could turn it off.)
>
> So I am confused.
>
> -T
>


Re: definition confusion of + and +^

2020-01-18 Thread Brad Gilbert
Most operators in Raku are subroutines.

1 + 2
infix:<+>( 1, 2 )

-1
prefix:<->( 1 )

You can add your own operators by creating such a subroutine.

sub postfix: ( UInt \n ) { [×] 2..n }

say 5!; # 120

Because it is so easy to add operators. Operators only do one thing.

1 + 2

That operator is for doing numeric addition.
If the two things are not numbers they get turned into numbers

['a'] + ['b', 'c'] # exactly the same as 1 + 2

The +^ operator is about Integers. So if you give it something that is not
an integer it becomes one.

1.2 +^ 1; # exactly the same as 1 +^ 1

---

Note that Int:D does NOT do any coercions.

Int:D() does do coercions.

Specifically Int:D() is short for Int:D(Any). Which means it coerces from
Any to Int, and the result must be defined.

On Sat, Jan 18, 2020 at 2:39 PM ToddAndMargo via perl6-users <
perl6-us...@perl.org> wrote:

> Hi All,
>
> Okay, I clearly do not understand what is
> going on with these definitions, so please
> correct my assumptions!
>
>
> https://docs.raku.org/language/operators#infix_+
> https://docs.raku.org/routine/+$CIRCUMFLEX_ACCENT
>
> Question: would some kind soul please tell me how:
>
>   multi sub infix:<+>($a, $b --> Numeric:D)
>   multi sub infix:<+^>($a, $b --> Int:D)
>
> gets turned into
>
>   $c = $a +  $b,   and
>   $c = $a +^ $b
>
>
> This is what I understand so far about
> the definition lines:
>
> 1)  "multi" means there a several way to do things
>
> 2)  "sub" means subroutine:  $c = +($a, $b)
>
>  my $a=2; my $b=3; my $c = +($a, $b)
>  2
>
>   And a participation trophy for the wrong answer.
>
>  my $a=2; my $b=3; my $c = +^($a, $b)
>  -3
>
>   And I just won two a participation trophies!
>
>
> 3)  <> is a form of literal quote
>
> 4)  infix:<+> means you can call it as a sub that
>  gives you back the wrong answer.
>
>  $c = +($a, $b)
>  $c = +^($a, $b)
>
> 5)  --> Numeric:D means it return a Numeric and
>  --> Int:D means it "coerces" your stuff and
>  return an Int, like it or not.
>
> Yours in confusion,
> -T
>


Re: definition confusion of + and +^

2020-01-18 Thread Curt Tilmes
On Sat, Jan 18, 2020, 3:39 PM ToddAndMargo via perl6-users <
perl6-us...@perl.org> wrote:

>
> 4)  infix:<+> means you can call it as a sub that
>  gives you back the wrong answer.
>
>  $c = +($a, $b)
>  $c = +^($a, $b)
>

You left off the infix:<> part of the sub's name.


Re: definition confusion of + and +^

2020-01-18 Thread Veesh Goldman
Hi Todd,
I would suggest reading https://docs.raku.org/language/optut.

For a slightly more thorough read
https://docs.raku.org/language/functions#Defining_operators.

On Sat, Jan 18, 2020 at 10:39 PM ToddAndMargo via perl6-users <
perl6-us...@perl.org> wrote:

> Hi All,
>
> Okay, I clearly do not understand what is
> going on with these definitions, so please
> correct my assumptions!
>
>
> https://docs.raku.org/language/operators#infix_+
> https://docs.raku.org/routine/+$CIRCUMFLEX_ACCENT
>
> Question: would some kind soul please tell me how:
>
>   multi sub infix:<+>($a, $b --> Numeric:D)
>   multi sub infix:<+^>($a, $b --> Int:D)
>
> gets turned into
>
>   $c = $a +  $b,   and
>   $c = $a +^ $b
>
>
> This is what I understand so far about
> the definition lines:
>
> 1)  "multi" means there a several way to do things
>
> 2)  "sub" means subroutine:  $c = +($a, $b)
>
>  my $a=2; my $b=3; my $c = +($a, $b)
>  2
>
>   And a participation trophy for the wrong answer.
>
>  my $a=2; my $b=3; my $c = +^($a, $b)
>  -3
>
>   And I just won two a participation trophies!
>
>
> 3)  <> is a form of literal quote
>
> 4)  infix:<+> means you can call it as a sub that
>  gives you back the wrong answer.
>
>  $c = +($a, $b)
>  $c = +^($a, $b)
>
> 5)  --> Numeric:D means it return a Numeric and
>  --> Int:D means it "coerces" your stuff and
>  return an Int, like it or not.
>
> Yours in confusion,
> -T
>


definition confusion of + and +^

2020-01-18 Thread ToddAndMargo via perl6-users

Hi All,

Okay, I clearly do not understand what is
going on with these definitions, so please
correct my assumptions!


https://docs.raku.org/language/operators#infix_+
https://docs.raku.org/routine/+$CIRCUMFLEX_ACCENT

Question: would some kind soul please tell me how:

 multi sub infix:<+>($a, $b --> Numeric:D)
 multi sub infix:<+^>($a, $b --> Int:D)

gets turned into

 $c = $a +  $b,   and
 $c = $a +^ $b


This is what I understand so far about
the definition lines:

1)  "multi" means there a several way to do things

2)  "sub" means subroutine:  $c = +($a, $b)

my $a=2; my $b=3; my $c = +($a, $b)
2

 And a participation trophy for the wrong answer.

my $a=2; my $b=3; my $c = +^($a, $b)
-3

 And I just won two a participation trophies!


3)  <> is a form of literal quote

4)  infix:<+> means you can call it as a sub that
gives you back the wrong answer.

$c = +($a, $b)
$c = +^($a, $b)

5)  --> Numeric:D means it return a Numeric and
--> Int:D means it "coerces" your stuff and
return an Int, like it or not.

Yours in confusion,
-T


Re: problems with xor

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-18 06:09, Tobias Boege wrote:

On Fri, 17 Jan 2020, ToddAndMargo via perl6-users wrote:

Hi All,

https://docs.raku.org/routine/+$CIRCUMFLEX_ACCENT

(Operators) infix +^§

multi sub infix:<+^>($a, $b --> Int:D)

Integer bitwise XOR operator: Coerces both arguments to Int and does a
bitwise XOR (exclusive OR) operation.


$ p6 'my uint8 $x=0b0101_0111; my uint8 $y = 0b_; my uint8 $z =
+^($x, $y ); say "0", $x.base(2); say "", $y.base(2); say $z.base(2);'

01010111

1101


XOR
A  B   A xor B
0  0  0
1  0  1
0  1  1
1  1  0

That s not what I am seeing above.

What am I doing wrong this time?

And who set the high bit making $z negative?



As was already mentioned, if you want to use the :<+^> operator,
you have to either call it by its full name as a sub:

   :<+^>($x, $y)

or you have to use it according to its syntax category, as an infix:

   $x +^ $y

When you write +^($x,$y), its cousin :<+^> is called instead,
because now you use +^ as a prefix operator. That one performs bitwise
negation on its argument coerced to Int, and since you pass it a list
of length two, you actually evaluate +^2. And that's how you get the
high bit and a value of -3.

Regards,
Tobias



Hi Tobias,

This works perfectly using the syntax $a = $b +^ $c

p6 'my uint8 $x=0b0101_0111; my uint8 $y = 0b_; my uint8 $z = $x 
+^ $y; say "0", $x.base(2); say "", $y.base(2); say "0",$z.base(2);'


01010111# $x
# $y
01011000# z = x xor y


But what is now confusing me is $c = +^( $a, $b )

p6 'my uint8 $x=0b0101_0111; my uint8 $y = 0b_; my uint8 $z = 
+^($x, $y); say "0", $x.base(2); say "", $y.base(2); say $z.base(2);'


01010111# $x
# $y
1101# z is not  x xor y

Which is clearly not correct.  The manual states:

  Integer bitwise XOR operator: Coerces both
  arguments to Int and does a bitwise XOR
  (exclusive OR) operation.

In my example run line, I purposefully left the
high bit off to keep overly helpful Raku from thinking
I had a negative number when it annoyingly overrules
my choice of native type.  (Ordinarily I like this
feature, except when doing bitwise operations, I
wish I could turn it off.)

So I am confused.

-T


Re: problems with xor

2020-01-18 Thread ToddAndMargo via perl6-users

On 2020-01-17 22:26, Darren Duncan wrote:

On 2020-01-17 9:00 p.m., ToddAndMargo via perl6-users wrote:

Still don't know what they used the word "sub"


The term "sub" is short for "subroutine", and declaring routines that 
way is part of the Perl legacy that lasted into Raku. -- Darren Duncan


I figured that.

What I don't get is how to call it as a sub.


Re: Ping JJ: string literals

2020-01-18 Thread Paul Procacci
Thank you Tobias.

This is what I was trying to get at, but wasn't sure _how_ to reach that
conclusion.
You've done so elegantly.

~Paul

On Sat, Jan 18, 2020 at 7:55 AM Tobias Boege  wrote:

> On Sat, 18 Jan 2020, JJ Merelo wrote:
> > The example works perfectly, and it does because it's a string literal
> > which is already 0 terminated. Let's use this code instead of the one
> that
> > I used in my other mail about this (which you probably didn't read
> anyway):
> >
> > 8< 8< 8<
> >
> > What does this mean? It means that NativeCall does the right call
> > (badum-t) and converts a Raku string literal into a C string literal,
> > inserting the null termination even if we didn't. I actually don't care
> if
> > it was the NativeCall API or the encode method. It just works. It gets
> > allocated the right amount of memory, it gets passed correctly into the C
> > realm. Just works. Since @array.elems has 3 elements, well, it might be
> > rather the C part the one that does that. But I really don't care, and it
> > does not really matter, and thus the example is correct, no need to add
> > anything else to the documentation. Except maybe "get your C right"
> >
>
> What you say seems to be correct: if you have a string literal in your
> Raku code, this works for me, too. (Sometimes, see below.)
>
> BUT the terminating NUL character is not inserted by NativeCall and it
> isn't inserted by  If you run this program which uses a much
> longer string that is not a literal on the face of it:
>
> use NativeCall;
> sub c-printf(CArray[uint8]) is native is symbol { * };
>
> my $string = "X" x 1994;
> my $array = CArray[uint8].new($string.encode.list);
> c-printf $array;
>
> through valgrind, it will warn you about a one-character invalid read,
> that is a byte accessed by printf() which is at offset 0 after a properly
> allocated block of size 1994:
>
> $ perl6-valgrind-m -MNativeCall -e 'sub c-printf(CArray[uint8]) is
> native is symbol { * }; my $string = "X" x 1994; my $array =
> CArray[uint8].new($string.encode.list); c-printf $array' >/dev/null
>
> ==325957== Invalid read of size 1
> ==325957==at 0x48401FC: strchrnul (vg_replace_strmem.c:1395)
> ==325957==by 0x50CD334: __vfprintf_internal (in /usr/lib/
> libc-2.30.so)
> ==325957==by 0x50BA26E: printf (in /usr/lib/libc-2.30.so)
> ==325957==by 0x4B58048: ??? (in $rakudo/install/lib/libmoar.so)
> ==325957==by 0x1FFEFFFB5F: ???
> ==325957==by 0x4B57F81: dc_callvm_call_x64 (in
> $rakudo/install/lib/libmoar.so)
> ==325957==by 0x50BA1BF: ??? (in /usr/lib/libc-2.30.so)
> ==325957==by 0xA275E3F: ???
> ==325957==by 0x990153F: ???
> ==325957==by 0xA275E3F: ???
> ==325957==by 0x1FFEFFFB7F: ???
> ==325957==by 0x4B578D1: dcCallVoid (in
> $rakudo/install/lib/libmoar.so)
> ==325957==  Address 0xb5ebf1a is 0 bytes after a block of size 1,994
> alloc'd
> ==325957==at 0x483AD7B: realloc (vg_replace_malloc.c:836)
> ==325957==by 0x4A9DFDF: expand.isra.3 (in
> $rakudo/install/lib/libmoar.so)
> ==325957==by 0x4A9E6F4: bind_pos (in
> $rakudo/install/lib/libmoar.so)
> ==325957==by 0x4A2C9AF: MVM_interp_run (in
> $rakudo/install/lib/libmoar.so)
> ==325957==by 0x4B2CC24: MVM_vm_run_file (in
> $rakudo/install/lib/libmoar.so)
> ==325957==by 0x109500: main (in $rakudo/install/bin/perl6-m)
>
> This is the NUL byte that happens to be there and terminate our string
> correctly, but nothing in the moarvm process has allocated it, because
> knowing what is allocated and what isn't is valgrind's job. And if it's
> not allocated, then either moarvm routinely writes NULs to memory it
> doesn't own or it simply does not automatically insert a NUL after the
> storage of every CArray[uint8]. And why would it? I for one would not
> expect CArray[uint8] to have special precautions built in for when it's
> used to hold a C string.
>
> Why does it work with a string literal in the Raku code? I don't know,
> but consider the following variations of the code, with my oldish Rakudo:
>
>   - with $string = "X" x 1994: valgrind sad
>   - with $string = "X" x 4:valgrind sad
>   - with $string = "X" x 3:valgrind happy
>   - with $string = "X" x 2:valgrind happy
>   - with $string a short literal
> like "FOO":valgrind happy
>   - with $string a literal of
> sufficient length like "FOOO": valgrind sad
>   - with $string = "FOO" x 2:  valgrind happy
>   - with $string = "FOO" x 200:valgrind sad
>
> My guess is that if it's sufficiently small and easy, then it is computed
> at compile-time and stored somewhere in the bytecode, for which some
> serialization routine ensures a trailing NUL byte inside an allocated
> region of memory for the process.
>
> That is only a barely informed guesses, but independently of what causes
> it to work on short string literals, I strongly believe 

Re: problems with xor

2020-01-18 Thread Tobias Boege
On Fri, 17 Jan 2020, ToddAndMargo via perl6-users wrote:
> Hi All,
> 
> https://docs.raku.org/routine/+$CIRCUMFLEX_ACCENT
> 
> (Operators) infix +^§
> 
> multi sub infix:<+^>($a, $b --> Int:D)
> 
> Integer bitwise XOR operator: Coerces both arguments to Int and does a
> bitwise XOR (exclusive OR) operation.
> 
> 
> $ p6 'my uint8 $x=0b0101_0111; my uint8 $y = 0b_; my uint8 $z =
> +^($x, $y ); say "0", $x.base(2); say "", $y.base(2); say $z.base(2);'
> 
> 01010111
> 
> 1101
> 
> 
> XOR
> A  B   A xor B
> 0  0  0
> 1  0  1
> 0  1  1
> 1  1  0
> 
> That s not what I am seeing above.
> 
> What am I doing wrong this time?
> 
> And who set the high bit making $z negative?
> 

As was already mentioned, if you want to use the :<+^> operator,
you have to either call it by its full name as a sub:

  :<+^>($x, $y)

or you have to use it according to its syntax category, as an infix:

  $x +^ $y

When you write +^($x,$y), its cousin :<+^> is called instead,
because now you use +^ as a prefix operator. That one performs bitwise
negation on its argument coerced to Int, and since you pass it a list
of length two, you actually evaluate +^2. And that's how you get the
high bit and a value of -3.

Regards,
Tobias

-- 
"There's an old saying: Don't change anything... ever!" -- Mr. Monk


Re: Ping JJ: string literals

2020-01-18 Thread JJ Merelo
El sáb., 18 ene. 2020 a las 13:55, Tobias Boege ()
escribió:

> On Sat, 18 Jan 2020, JJ Merelo wrote:
> > The example works perfectly, and it does because it's a string literal
> > which is already 0 terminated. Let's use this code instead of the one
> that
> > I used in my other mail about this (which you probably didn't read
> anyway):
> >
> > 8< 8< 8<
> >
> > What does this mean? It means that NativeCall does the right call
> > (badum-t) and converts a Raku string literal into a C string literal,
> > inserting the null termination even if we didn't. I actually don't care
> if
> > it was the NativeCall API or the encode method. It just works. It gets
> > allocated the right amount of memory, it gets passed correctly into the C
> > realm. Just works. Since @array.elems has 3 elements, well, it might be
> > rather the C part the one that does that. But I really don't care, and it
> > does not really matter, and thus the example is correct, no need to add
> > anything else to the documentation. Except maybe "get your C right"
> >
>
> What you say seems to be correct: if you have a string literal in your
> Raku code, this works for me, too. (Sometimes, see below.)
>
> BUT the terminating NUL character is not inserted by NativeCall and it
> isn't inserted by  If you run this program which uses a much
> longer string that is not a literal on the face of it:
>
> use NativeCall;
> sub c-printf(CArray[uint8]) is native is symbol { * };
>
> my $string = "X" x 1994;
> my $array = CArray[uint8].new($string.encode.list);
> c-printf $array;
>
> through valgrind, it will warn you about a one-character invalid read,
> that is a byte accessed by printf() which is at offset 0 after a properly
> allocated block of size 1994:
>
> $ perl6-valgrind-m -MNativeCall -e 'sub c-printf(CArray[uint8]) is
> native is symbol { * }; my $string = "X" x 1994; my $array =
> CArray[uint8].new($string.encode.list); c-printf $array' >/dev/null
>
> ==325957== Invalid read of size 1
> ==325957==at 0x48401FC: strchrnul (vg_replace_strmem.c:1395)
> ==325957==by 0x50CD334: __vfprintf_internal (in /usr/lib/
> libc-2.30.so)
> ==325957==by 0x50BA26E: printf (in /usr/lib/libc-2.30.so)
> ==325957==by 0x4B58048: ??? (in $rakudo/install/lib/libmoar.so)
> ==325957==by 0x1FFEFFFB5F: ???
> ==325957==by 0x4B57F81: dc_callvm_call_x64 (in
> $rakudo/install/lib/libmoar.so)
> ==325957==by 0x50BA1BF: ??? (in /usr/lib/libc-2.30.so)
> ==325957==by 0xA275E3F: ???
> ==325957==by 0x990153F: ???
> ==325957==by 0xA275E3F: ???
> ==325957==by 0x1FFEFFFB7F: ???
> ==325957==by 0x4B578D1: dcCallVoid (in
> $rakudo/install/lib/libmoar.so)
> ==325957==  Address 0xb5ebf1a is 0 bytes after a block of size 1,994
> alloc'd
> ==325957==at 0x483AD7B: realloc (vg_replace_malloc.c:836)
> ==325957==by 0x4A9DFDF: expand.isra.3 (in
> $rakudo/install/lib/libmoar.so)
> ==325957==by 0x4A9E6F4: bind_pos (in
> $rakudo/install/lib/libmoar.so)
> ==325957==by 0x4A2C9AF: MVM_interp_run (in
> $rakudo/install/lib/libmoar.so)
> ==325957==by 0x4B2CC24: MVM_vm_run_file (in
> $rakudo/install/lib/libmoar.so)
> ==325957==by 0x109500: main (in $rakudo/install/bin/perl6-m)
>
> This is the NUL byte that happens to be there and terminate our string
> correctly, but nothing in the moarvm process has allocated it, because
> knowing what is allocated and what isn't is valgrind's job. And if it's
> not allocated, then either moarvm routinely writes NULs to memory it
> doesn't own or it simply does not automatically insert a NUL after the
> storage of every CArray[uint8]. And why would it? I for one would not
> expect CArray[uint8] to have special precautions built in for when it's
> used to hold a C string.
>
> Why does it work with a string literal in the Raku code? I don't know,
> but consider the following variations of the code, with my oldish Rakudo:
>
>   - with $string = "X" x 1994: valgrind sad
>   - with $string = "X" x 4:valgrind sad
>   - with $string = "X" x 3:valgrind happy
>   - with $string = "X" x 2:valgrind happy
>   - with $string a short literal
> like "FOO":valgrind happy
>   - with $string a literal of
> sufficient length like "FOOO": valgrind sad
>   - with $string = "FOO" x 2:  valgrind happy
>   - with $string = "FOO" x 200:valgrind sad
>
> My guess is that if it's sufficiently small and easy, then it is computed
> at compile-time and stored somewhere in the bytecode, for which some
> serialization routine ensures a trailing NUL byte inside an allocated
> region of memory for the process.
>
> That is only a barely informed guesses, but independently of what causes
> it to work on short string literals, I strongly believe that this is an
> implementation detail and hence I would call the example in the docs
> misleading. Appending the ", 0" when 

Re: Ping JJ: string literals

2020-01-18 Thread Tobias Boege
On Sat, 18 Jan 2020, JJ Merelo wrote:
> The example works perfectly, and it does because it's a string literal
> which is already 0 terminated. Let's use this code instead of the one that
> I used in my other mail about this (which you probably didn't read anyway):
> 
> 8< 8< 8<
> 
> What does this mean? It means that NativeCall does the right call
> (badum-t) and converts a Raku string literal into a C string literal,
> inserting the null termination even if we didn't. I actually don't care if
> it was the NativeCall API or the encode method. It just works. It gets
> allocated the right amount of memory, it gets passed correctly into the C
> realm. Just works. Since @array.elems has 3 elements, well, it might be
> rather the C part the one that does that. But I really don't care, and it
> does not really matter, and thus the example is correct, no need to add
> anything else to the documentation. Except maybe "get your C right"
> 

What you say seems to be correct: if you have a string literal in your
Raku code, this works for me, too. (Sometimes, see below.)

BUT the terminating NUL character is not inserted by NativeCall and it
isn't inserted by  If you run this program which uses a much
longer string that is not a literal on the face of it:

use NativeCall;
sub c-printf(CArray[uint8]) is native is symbol { * };

my $string = "X" x 1994;
my $array = CArray[uint8].new($string.encode.list);
c-printf $array;

through valgrind, it will warn you about a one-character invalid read,
that is a byte accessed by printf() which is at offset 0 after a properly
allocated block of size 1994:

$ perl6-valgrind-m -MNativeCall -e 'sub c-printf(CArray[uint8]) is native 
is symbol { * }; my $string = "X" x 1994; my $array = 
CArray[uint8].new($string.encode.list); c-printf $array' >/dev/null

==325957== Invalid read of size 1
==325957==at 0x48401FC: strchrnul (vg_replace_strmem.c:1395)
==325957==by 0x50CD334: __vfprintf_internal (in /usr/lib/libc-2.30.so)
==325957==by 0x50BA26E: printf (in /usr/lib/libc-2.30.so)
==325957==by 0x4B58048: ??? (in $rakudo/install/lib/libmoar.so)
==325957==by 0x1FFEFFFB5F: ???
==325957==by 0x4B57F81: dc_callvm_call_x64 (in 
$rakudo/install/lib/libmoar.so)
==325957==by 0x50BA1BF: ??? (in /usr/lib/libc-2.30.so)
==325957==by 0xA275E3F: ???
==325957==by 0x990153F: ???
==325957==by 0xA275E3F: ???
==325957==by 0x1FFEFFFB7F: ???
==325957==by 0x4B578D1: dcCallVoid (in $rakudo/install/lib/libmoar.so)
==325957==  Address 0xb5ebf1a is 0 bytes after a block of size 1,994 alloc'd
==325957==at 0x483AD7B: realloc (vg_replace_malloc.c:836)
==325957==by 0x4A9DFDF: expand.isra.3 (in 
$rakudo/install/lib/libmoar.so)
==325957==by 0x4A9E6F4: bind_pos (in $rakudo/install/lib/libmoar.so)
==325957==by 0x4A2C9AF: MVM_interp_run (in 
$rakudo/install/lib/libmoar.so)
==325957==by 0x4B2CC24: MVM_vm_run_file (in 
$rakudo/install/lib/libmoar.so)
==325957==by 0x109500: main (in $rakudo/install/bin/perl6-m)

This is the NUL byte that happens to be there and terminate our string
correctly, but nothing in the moarvm process has allocated it, because
knowing what is allocated and what isn't is valgrind's job. And if it's
not allocated, then either moarvm routinely writes NULs to memory it
doesn't own or it simply does not automatically insert a NUL after the
storage of every CArray[uint8]. And why would it? I for one would not
expect CArray[uint8] to have special precautions built in for when it's
used to hold a C string.

Why does it work with a string literal in the Raku code? I don't know,
but consider the following variations of the code, with my oldish Rakudo:

  - with $string = "X" x 1994: valgrind sad
  - with $string = "X" x 4:valgrind sad
  - with $string = "X" x 3:valgrind happy
  - with $string = "X" x 2:valgrind happy
  - with $string a short literal
like "FOO":valgrind happy
  - with $string a literal of
sufficient length like "FOOO": valgrind sad
  - with $string = "FOO" x 2:  valgrind happy
  - with $string = "FOO" x 200:valgrind sad

My guess is that if it's sufficiently small and easy, then it is computed
at compile-time and stored somewhere in the bytecode, for which some
serialization routine ensures a trailing NUL byte inside an allocated
region of memory for the process.

That is only a barely informed guesses, but independently of what causes
it to work on short string literals, I strongly believe that this is an
implementation detail and hence I would call the example in the docs
misleading. Appending the ", 0" when constructing the CArray[uint8]
seems like a really neat fix.

Anyway, the most important message of this mail should actually be:
_Normally_, the way you pass a Raku string to a native function is by
using the `is encoded` trait. It's such a nice way 

Re: Ping JJ: string literals

2020-01-18 Thread JJ Merelo
I know this is utterly and absolutely absurd, but so it goes.

El vie., 17 ene. 2020 a las 23:28, ToddAndMargo ()
escribió:

> Hi JJ,
>
> Please be my hero.
>
> I won't call you any goofy names out of
> affection and friendship, as others will get
> their nickers in a twist.
>
> This is from a previous conversation we had concerning
> the mistake in
>
> https://docs.raku.org/language/nativecall#index-entry-nativecall
>
>  my $string = "FOO";
>  ...
>  my $array = CArray[uint8].new($string.encode.list);
>
>
> Todd:
>  By the way, "C String" REQUIRES a nul at the end:
>  an error in the NativeCall documentation.
>
> JJ:
>  No, it does not. And even if it did, it should better
>  go to the C, not Raku, documentation
>

A C string literal is a C string. It automatically gets null terminated. I
already mentioned this link
https://stackoverflow.com/questions/8202897/null-terminated-string-in-c,
but you don't seem to like and read links, so I copy the good bits here;

"Is it absolutely necessary? *No*, because when you call scanf, strcpy(except
for strncpy where you need to manually put zero if it exceeds the size), it
copies the null terminator for you. Is it good to do it anyways? *Not
really*, it doesn't really help the problem of bufferoverflow since those
function will go over the size of the buffer anyways. Then what's the best
way? use c++ with std::string."

And another answer:

"Always be careful to allocate enough memory with strings, compare the
effects of the following lines of code:

char s1[3] = "abc";char s2[4] = "abc";char s3[] = "abc";

All three are considered legal lines of code (
http://c-faq.com/ansi/nonstrings.htmlhttp://c-faq.com/ansi/nonstrings.html),
but in the first case, there isn't enough memory for the fourth
null-terminated character. s1 will not behave like a normal string, but s2
and s3 will. The compiler automatically count for s3, and you get four
bytes of allocated memory. If you try to write

"

>
>
> And that would be a "String Literal", which is NOT
> a C String.  And C's documentation is precise and
> clear (n1570).  It is not their problem.  It
> is a mistake in NativeCall's documentation.
>

Did you really read what you wrote? A string literal is not a C string? And
you want to add that to NativeCall documentation? You really seem to be
driven by your need to prove you're right, than by a genuine wish to
improve the documentation. Which I insist, is for Raku, not for C.

>
> Without the nul at the end, the string is considered
> "undefined".
>

No, it's not. Please read the answer in StackOverflow above. If you use
string literals and don't assign enough memory for the null termination,
it's going to be undefined. That's the case for s1 above. Again, C stuff.
There's enough work as it is now to document the finer points of Raku. Only
with the "new" ( = 1 year old) 6.d Raku behavior, there're still almost 100
items to document. Document the finer points of C is totally outside the
scope. Just read (maybe implicitly) at the beginning of NativeCall "Get
your C right" and that's it. I'm not gonna go further than that.

>
> The C guys have been helping me with definitions.  Chapter and
> verse would be :
>
> INTERNATIONAL STANDARD ©ISO/IEC ISO/IEC 9899:201x
> Programming languages — C
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
>
>  5.2.1 Character sets
>  7.1.1 Definitions of terms
>  6.7.9,p14 Semantics
>
> Here is your String Literal, which you are confusing
> with a c string:
>
> 6.7.9,p14 states:
>
>  An array of character type may be initialized by a
>  character string literal or UTF−8 string literal,
>  optionally enclosed in braces. Successive bytes
>  of the string literal (including the terminating
>  null character if there is room or if the array
>  is of unknown size) initialize the elements of
>  the array.
>
> So there is the unnecessary nul you speak of, except,
> again, it is not a C String.  So you do have a
>

Are you _really_ saying we should put parts of the C standard in the Raku
documentation? Again, did you read what you wrote?

somewhat of a point, although not a good one as
> it will throw those trying to use the docs into
> a state of confusion wondering what is going wrong,
> as it did me.
>

They should have read the (implicit) notice at the beginning of NativeCall:
"Get your C right"


> It about killed me to figure it our myself.  I
> don't want others to go through the same pain
> over a simple mistake in the documentation.
>

Well, an omission has suddenly be converted into a mistake. And an example
which is totally correct (as proven several times) too. We do live in
curious times. (Also, I didn't write that)


> Now the C guys told me that the reason why I am not
> getting anywhere with you is that I provided a bad
> example.  They proceeded to give me an example
> that precisely shows the careening make by
> the mistake in the documentation:
>
>
> An example