ChanServ changed the topic of #picolisp to: PicoLisp language | Channel Log: https://irclog.whitequark.org/picolisp/ | Check also http://www.picolisp.com for more information
beneroth_ has joined #picolisp
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
<aw-> (native "lib.so" "fun" 'I '(Msg (8192 C . 8192) 0) 8192)
<Regenaxer> yes
<Regenaxer> but better perhaps malloc a buffer
<Regenaxer> or use 'buf' in pil21
<aw-> what's the difference?
<aw-> safer?
<Regenaxer> diff between buf and malloc?
<aw-> no no, diff between using the structure i wrote above
<aw-> VS malloc a buffer
<aw-> manual vs auto malloc
<Regenaxer> you get a string
<Regenaxer> not a list of 8000 chars
<aw-> ohhhh
<aw-> i like that
<Regenaxer> buf or malloc gives a pointer
<Regenaxer> you can then strdup
<aw-> hmmm
<aw-> ok wait
<aw-> let me try
<aw-> ok yeah, i get a big int back
<Regenaxer> (let P (... malloc) ... (native "lib.so" "fun" 'I P) (... strdup P) ... (free P]
<Regenaxer> IIRC pil21 does not need the strdup
<Regenaxer> 'struct' can do it directly
<aw-> hmmm
<aw-> ok i have the _exact_ same problem with strdup
<aw-> extra garbage at the end of the string
<Regenaxer> then it is not null-terminated
<aw-> :O
<aw-> omg
<aw-> i hope you're wrong
<aw-> ahjahahha
<aw-> wait let me check
<Regenaxer> then strndup() ?
beneroth_ has quit [Quit: Leaving]
beneroth has joined #picolisp
<Regenaxer> Just for the records: In pil21 (struct P 'S) should be the same as (%@ "strdup" 'S P)
<Regenaxer> (if I remember right ;)
<Regenaxer> struct should be a little faster
<aw-> awesome!
<Regenaxer> but that is not supported in pil64
<Regenaxer> pil21/doc/diff says "'struct' Useful atomic result specifications"
<Regenaxer> in pil64 always a list was returned
<Regenaxer> I used that new feature in @lib/net.l
<aw-> ok i fixed the problem Regenaxer
<aw-> the string i was sending _was_ null terminated, but i had to send the length+1
<aw-> instead of length
<aw-> so now i read and there's no junk at the end, just 1 extra byte
<Regenaxer> cool!
<aw-> can you explain more in detail why the malloc+strndup is better than picolisp auto-malloc?
<Regenaxer> "the string i was sending" means from another C function?
<aw-> i'm not sure i fully understand
<aw-> yes from another C function
<Regenaxer> auto-malloc is indeed better, but there is no good way to extract a string from that
<aw-> why wouldnt malloc/strdup reading all 80000 characters?
<Regenaxer> the arg to fun is not a structure
<aw-> err
<aw-> why wouldnt strdup read all 8000 characters in the buffer?
<aw-> it stops at \0 ?
<Regenaxer> no, strdup reads up to null
<Regenaxer> yes
<aw-> ahhhhhh
<Regenaxer> We must alloc the bytes somehow
<Regenaxer> auto, buf or malloc
<Regenaxer> but auto means a structure
<Regenaxer> not a plain pointer
<aw-> if I do '(Msg (8192 C . 8192)) then i will read all 8192 bytes?
<Regenaxer> yes
<Regenaxer> the whole struct
<aw-> evne if they are 0?
<aw-> even*
<Regenaxer> yes, it says we have a struct of 8192 chars
<aw-> ah
<aw-> i see
<Regenaxer> here we have not a struct, but just a pointer to a string
<Regenaxer> kind of different
<aw-> right
<aw-> we know there's no need for the entire 8192 bytes (unless it's a really longstring)
<Regenaxer> yeah, and we know we can stop before
<aw-> great
<aw-> native is so mind twisting :\
<aw-> well, still easier than Haskell ;)
<Regenaxer> So the problem is that native has no direct syntax for it
<Regenaxer> it needs 'struct' or malloc etc
<aw-> right right, but you solved some of that in pil21
<aw-> or at least, simplified some
<Regenaxer> Just a little more useful syntax
<Regenaxer> yes
<Regenaxer> It can return scalars now
<Regenaxer> insted of always a list of struct items
<Regenaxer> I needed that in net.l
<aw-> oh, side note
<aw-> are you on android now?
<Regenaxer> yes
<Regenaxer> termux
<aw-> can you tell me the value of O_CLOEXEC ?
<aw-> picolisp doesn't seem to define it
<aw-> only FD_CLOEXEC
<Regenaxer> must be in sys/arm64...
<Regenaxer> (equ FD_CLOEXEC 1)
<aw-> no
<aw-> no FD_CLOEXEC
<aw-> O_CLOEXEC
<Regenaxer> it is not there
<Regenaxer> needs a C program
<aw-> i know, that's why i ask you
<aw-> on Linux arm64 it's 524288
jibanes has quit [Ping timeout: 240 seconds]
<Regenaxer> let me check
<aw-> i think.. had to look in some .h files
<Regenaxer> yes, but manually parsing .h is error prone
<Regenaxer> we don't know the ifdefs
<aw-> i might be wrong
<Regenaxer> I grep the includes, moment
<Regenaxer> the includes in Termux
<Regenaxer> http://ix.io/2xCI
jibanes has joined #picolisp
<Regenaxer> So it seems 02000000
<Regenaxer> yes
<Regenaxer> : (oct "02000000")
<Regenaxer> -> 524288
<aw-> ok same here
<Regenaxer> T
<aw-> different on BSD* though
<aw-> it's nice you don't have to define these in pil21
<Regenaxer> At least it is more clean via sysdefs
<aw-> yes
aw- has quit [Quit: Leaving.]
orivej has joined #picolisp
orivej has quit [Ping timeout: 260 seconds]
rob_w has quit [Quit: Leaving]
rob_w has joined #picolisp
aw- has joined #picolisp
orivej has joined #picolisp
DKordic has joined #picolisp
jibanes has quit [Ping timeout: 258 seconds]
jibanes has joined #picolisp
mtsd_ has joined #picolisp
mtsd has quit [Ping timeout: 240 seconds]
mtsd_ has quit [Client Quit]
aw- has quit [Quit: Leaving.]
DKordic has quit [Ping timeout: 244 seconds]
tankf33der_ has joined #picolisp
tankf33der has quit [Ping timeout: 272 seconds]
jibanes has quit [Ping timeout: 240 seconds]
jibanes has joined #picolisp
rob_w has quit [Quit: Leaving]
jibanes has quit [Ping timeout: 272 seconds]
jibanes has joined #picolisp
tankf33der_ has left #picolisp [#picolisp]
tankf33der has joined #picolisp
<tankf33der> test
orivej has quit [Ping timeout: 260 seconds]
<Regenaxer> tankf33der, we have a problem with (key)
<Regenaxer> hangs if multi-byte characters
<Regenaxer> I debug over the next day(s)
<tankf33der> utf is correct itself.
<Regenaxer> Somehow seems to conflict with readline() and/or raw mode
<Regenaxer> yes, utf is ok
<Regenaxer> I experimented with raw mode in key
<Regenaxer> I think it is somewhere different
<Regenaxer> probably in waitFd
<Regenaxer> A single Kanji works for example
<Regenaxer> or a smiley
<Regenaxer> but a function key (e.g. F2) hangs
<Regenaxer> so the problem is not multi-byte char
<Regenaxer> this works
<Regenaxer> it is multiple bytes by one key stroke
<Regenaxer> 3 chars
<Regenaxer> like F2 is ESC + 2 bytes
<tankf33der> i have this issue in my list :)
<Regenaxer> ah, ok
<Regenaxer> In pil64:
<Regenaxer> : (make (link (key)) (while (key 100) (link @)))
<Regenaxer> -> ("^[" "O" "Q")
<Regenaxer> 3 bytes
<tankf33der> afk.
<Regenaxer> yes, arrow keys are like function keys
<Regenaxer> I'll find
<Regenaxer> see you!
orivej has joined #picolisp
orivej has quit [Ping timeout: 260 seconds]