beneroth has quit [Remote host closed the connection]
aw- has joined #picolisp
orivej has joined #picolisp
DKordic has quit [Ping timeout: 240 seconds]
jibanes has quit [Ping timeout: 256 seconds]
jibanes has joined #picolisp
<aw->
Regenaxer: morning, more (native) issues: I'm passing a struct as an argument, which expects some chars: 'char *msg_ptr'
<aw->
like this: (list '&msg (10 (C . 10)))
<aw->
but the function is returning more than it should
<aw->
wrong question
<aw->
how do I know how many characters to read?
<aw->
here i created an arbitrary 10-byte buffer.. but i might receive more or less than 10
<aw->
is there a way to know how much to read? or read until "\n" or something?
<aw->
my C function returns I, the number of bytes.. ex: 4 .. but because I use a 10-byte buffer, there's extra "junk" that seems to fill the buffer
<aw->
no idea what's going on, i should learn more C ;)
<aw->
.. anyways, I am using (head) to discard the extra chars returned in the buffer.. since the C functions returns the number of bytes, I can use that to shorten the list and get "exactly" the chars I need
<aw->
please confirm if that's the correct approach
<Regenaxer>
Good morning!
<Regenaxer>
Is the problem that chars are of variable size?
<Regenaxer>
1 ... 4 bytes per char
jibanes has quit [Ping timeout: 240 seconds]
<Regenaxer>
Can't you extract it as a null-terminated string? That takes care of char sizes
jibanes has joined #picolisp
<aw->
ah yes! null-terminated string..
<aw->
how?
<aw->
with S ?
<Regenaxer>
yes
<Regenaxer>
Normally strings in C are expected to be null-terminated. Unusual if they are not, but such cases exist of course
<aw->
in this case they are
<aw->
hmmm
<aw->
i try to extract it with '(&msg S)
<aw->
?
<aw->
no
<aw->
'(&msg (10) S . 0)
<aw->
no
<aw->
there are no examples for strings with (native)
<aw->
godddd
<aw->
native is so frustrating
<Regenaxer>
hmm
<Regenaxer>
Not (native "@" "getenv" 'S "TERM") ?
<aw->
in this example: (native "@" "read" 'N Fd '(Buf (4 B . 4)) 4)
<aw->
"The difference is that we wrote (B . 4) (a list of 4 bytes) instead of I"
<aw->
it's not (B . 4) it's (4 B . 4)
<aw->
what is (4 B . 4) ?
<Regenaxer>
it is char[4]
<Regenaxer>
4 is the size
<aw->
Regenaxer: no, the function returns an Int, the string (chars) are returned in a pointer argument
<Regenaxer>
and (B . 4) is the
<Regenaxer>
CDR
<Regenaxer>
then '(S ...)
<Regenaxer>
if the struct has char* there
<Regenaxer>
you have char[10] I suppose
<aw->
i think that example should be (5 B . 4) or something.. to clear what is 4 and 5
<aw->
instead 4
<Regenaxer>
yeah
<Regenaxer>
then '(B B B B)
<Regenaxer>
you get 4 bytes
<Regenaxer>
not chars
<aw->
right
<Regenaxer>
'(C C C C) gives 4 chars
<Regenaxer>
but may be longer than 4 bytes
<Regenaxer>
in memory
<Regenaxer>
the returned list has 4 chars then
<aw->
i get seg fault
<aw->
'(&msg (S))
<Regenaxer>
no
<Regenaxer>
'(C C C C)
<Regenaxer>
as the struct arg
<aw->
why ?
<Regenaxer>
4 chars
<aw->
i don't know the size of the data
<aw->
i know it's a null-terminated string
<Regenaxer>
ok, I must dig into it. Don't have the details present
<Regenaxer>
some weeks ago that I used native
<aw->
(list '&msg '(64 (S)) 0)
<aw->
this doesn't work
<aw->
but (list '&msg '(64 (C C C C)) 0) works
<Regenaxer>
forget &
<aw->
ok
<Regenaxer>
it is a normal char in pil
<aw->
yes i know
<aw->
ok i changed to Buf
<aw->
(list 'Buf '(64 (S)) 0) == no
<Regenaxer>
what definitely works if you take the address and native strdup
<Regenaxer>
but wait
<aw->
(list 'Buf '(64 (C C C C)) 0) == yes
<Regenaxer>
I must dig into it
<aw->
ok thanks
<Regenaxer>
'S' always needs a string *pointer*
<Regenaxer>
not a char *array*
<Regenaxer>
So the only *direct* way is (B . 4) and then operate on the list
<Regenaxer>
or you take the address (only in pil21 iirc)
<Regenaxer>
and (%@ "strdup" ) it
<Regenaxer>
C has no native "string" type
<Regenaxer>
only pointers to char arrays
<Regenaxer>
and you always know the (max) length
<aw->
ahhh
<Regenaxer>
I think there is a way with 'struct'
<aw->
ok so since it's char array, can I do (C . 4) ?
<Regenaxer>
yes
<aw->
or (C . 1000) ?
<Regenaxer>
or (B . 4)
<Regenaxer>
you must pass the correct size
<aw->
i dont know the size
<Regenaxer>
C *always* has a known array size
<aw->
yes but i don't know it until I read it
<Regenaxer>
it must be in the struct { ..}
<Regenaxer>
then you must take the address
<aw->
char *msg_ptr
<Regenaxer>
and 'S'
<Regenaxer>
is "char *msg_ptr" an element of the struct?
<Regenaxer>
Then we are back at 'S'
<aw->
no it's not a struct
<aw->
it's just a pointer
<aw->
to a char* array
<Regenaxer>
the "strdup"
<Regenaxer>
(%@ "strdup" 'S Adr)
<aw->
what is Adr ?
<Regenaxer>
the address
<Regenaxer>
obtained with 'N' (or 'P')
<aw->
hmmm
<aw->
ok wait
<aw->
can i just give an arbitrary buffer size?
<Regenaxer>
what for?
<Regenaxer>
(C . 1000) ?
<aw->
because the function returns an Int, which is the size of the string
<Regenaxer>
Not a good idea
<Regenaxer>
ah, ok
<Regenaxer>
but I think S is absolutely the way
<Regenaxer>
it is C
<Regenaxer>
null-terminated
<aw->
i tried and it kept crashing..
<aw->
with S
mtsd has joined #picolisp
<aw->
didnt do strdup
<aw->
but this seems like a long walk around something seemingly simple
<Regenaxer>
what is the signature of the C function?
<Regenaxer>
yes
<Regenaxer>
You must think in C data structures
<aw->
ssize_t fun ()
<Regenaxer>
can't be
<aw->
wait
<Regenaxer>
where is the string?
<aw->
ssize_t fun (char *msg_ptr)
<aw->
something like that
<Regenaxer>
so strdup or strndup
<Regenaxer>
easy
<aw->
ok but this annoys me
<aw->
because it's not in the native docs
<Regenaxer>
why not?
<aw->
i would never find that solution on my own
<Regenaxer>
the ref explains "Arguments can be ..."
<Regenaxer>
... structures, passed as lists
<Regenaxer>
But what you want is a return value
<aw->
ok wait
<aw->
let me try some things
<Regenaxer>
so you need a function that returns a string
<Regenaxer>
Telephone
<Regenaxer>
done
orivej has quit [Ping timeout: 256 seconds]
<Regenaxer>
hmm
<Regenaxer>
wait, sorry
<Regenaxer>
char *msg_ptr is for the return value?
<Regenaxer>
So it is '(Msg (S . 1)) or '(Msg S . 1)
<Regenaxer>
(%@ "fun" 'N '(Msg S . 1))
<Regenaxer>
then 'Msg' contains the transient symbol
rob_w has joined #picolisp
<aw->
doesn't work
<Regenaxer>
oops
<aw->
15428 No memory
<Regenaxer>
(%@ "fun" 'N '(Msg (S . 1)))
<Regenaxer>
Msg holds a list of a single symbol then
<Regenaxer>
sorry!
<aw->
same
<Regenaxer>
let me read the docs ;)
<aw->
the argument is a buffer
<aw->
or.. must be a buffer
<aw->
no problem
<Regenaxer>
the size is missing
<aw->
i got it working but it's a bit of a hack i think
<Regenaxer>
we need 8 for the size
<Regenaxer>
(%@ "fun" 'N '(Msg (8 S . 1)))
<Regenaxer>
should give a single-element list
<Regenaxer>
"a cons pair for the size and result specification in the CADR"
<Regenaxer>
So the size is 8 for a single pointer
<Regenaxer>
we pass a struct { char* }
<Regenaxer>
no initialization
<Regenaxer>
does that work?
<aw->
segfault
<Regenaxer>
hmm :(
<Regenaxer>
can't be ;)
<Regenaxer>
What does 'fun' expect?
<Regenaxer>
does it want a pointer to a pre-allocated buffer of a given size?
<Regenaxer>
what exactly does fun do?
<Regenaxer>
you pass a pointer? To where?
<Regenaxer>
how would you call fun() in C?
<Regenaxer>
hello?
<aw->
yes that's what it wants
<aw->
a pointer to a pre-allocated buffer
<Regenaxer>
but what size?
<aw->
arbitrary
<Regenaxer>
no
<Regenaxer>
that gives buffer overflow
<aw->
i can choose the buffer size to anything between 0 and 8192
<Regenaxer>
where do you tell that to 'fun'?
<aw->
so i did '(Msg (8192 C . 8192) 0)
<Regenaxer>
How does fun to know where to stop?
<aw->
2nd argument to fun is the size
<Regenaxer>
you did not write that in the signature above