How to effectively insert into string?
Hello, how do I write a function that inserts into a string (or deletes from a string) effectively in guile? There's some mention about how strings are implemented in the info manual, but it's not really clear to me. Is it necessary to implement a gap buffer / rope / something similar, or can it effectively be achieved with only guile's strings? I also have a related question. Let's say I have a spec file (as in the one used by RPM) and I need to add several lines to the section of patches which looks like this: ... Patch0001: ... Patch0002: ... Patch0003: ... ... That is, I'd like to process the file and add "Patch0004...\nPatch0005..." after the Patch0003 line, then save the file. What is the best way to do this in guile? Is it better to read the entire file and then use something like regexp-substitute or is there a better way? Thank you, -- Jan Synacek Software Engineer, Red Hat
Incomplete backtrace
Hello, consider the following piece of code: $ cat test.scm (use-modules (ice-9 regex)) (define (change text) (regexp-substitute #f (string-match "string" text) 'pre "something" 0 'post)) (define (main) (change "there will be no match")) (main) When I run the script, I get a backtrace: $ guile -s test.scm Backtrace: In ice-9/boot-9.scm: 1736:10 8 (with-exception-handler _ _ #:unwind? _ # _) In unknown file: 7 (apply-smob/0 #) In ice-9/boot-9.scm: 718:2 6 (call-with-prompt _ _ #) In ice-9/eval.scm: 619:8 5 (_ #(#(#))) In ice-9/boot-9.scm: 2806:4 4 (save-module-excursion _) 4351:12 3 (_) In ice-9/ports.scm: 550:4 2 (call-with-output-string _) In ice-9/boot-9.scm: 260:13 1 (for-each # …) In ice-9/regex.scm: 64:2 0 (_ _) Why do I not see the exact place where the problem is? Why are there underscores instead? Why do I not even see that the error originated in test.scm? I can't find any explanation about this in the manual. While this code was extracted from a bigger program and it's obvious where the problem is, it was super hard to figure it out in the original program. Because the backtrace actually doesn't even point in the right place, it's quite useless in my opinion. Am I doing anything wrong? I use guile 3.0.1. Regards, -- Jan Synacek Software Engineer, Red Hat
Re: Incomplete backtrace
On Wed, Mar 11, 2020 at 7:07 PM Jan Synacek wrote: > Hello, > > consider the following piece of code: > > $ cat test.scm > (use-modules (ice-9 regex)) > > (define (change text) > (regexp-substitute #f (string-match "string" text) > 'pre > "something" 0 > 'post)) > > (define (main) > (change "there will be no match")) > > (main) > > When I run the script, I get a backtrace: > > $ guile -s test.scm > Backtrace: > In ice-9/boot-9.scm: > 1736:10 8 (with-exception-handler _ _ #:unwind? _ # _) > In unknown file: >7 (apply-smob/0 #) > In ice-9/boot-9.scm: > 718:2 6 (call-with-prompt _ _ #) > In ice-9/eval.scm: > 619:8 5 (_ #(#(#))) > In ice-9/boot-9.scm: >2806:4 4 (save-module-excursion _) > 4351:12 3 (_) > In ice-9/ports.scm: > 550:4 2 (call-with-output-string _) > In ice-9/boot-9.scm: >260:13 1 (for-each # …) > In ice-9/regex.scm: > 64:2 0 (_ _) > I forgot one line in the backtrace output: ice-9/regex.scm:64:2: In procedure vector-ref: Wrong type argument in position 1 (expecting vector): #f Which sort of gives a hint, but not really... -- Jan Synacek Software Engineer, Red Hat
FFI questions
Hello, Currently I have something like this: (define libxcb (dynamic-link "libxcb")) ... (define c-change-window-attributes (pointer->procedure void (dynamic-func "xcb_change_window_attributes" libxcb) (list '* uint32 uint32 '*))) (define (change-window-attributes conn win mask vals) (c-change-window-attributes conn win mask (bytevector->pointer vals))) The last argument to xcb_change_window_attributes is 'const void *' and I need to pass a u32 vector to it. As it is right now, it segfaults when I try passing #u32(something) to 'change-window-attributes'. Is it possible to make it accept a u32 vector using just Scheme or do I have to work around it on the C level? My second question is about FFI and structs. Is it possible to access C struct members from Scheme by name? If not, how do I generally approach the problem? I've checked how guile-xcb does it and it seems to be building hash tables with field names as keys. But that basically requires me to "redefine" all the C structs that I would be interested in at the Scheme level. Regards, -- Jan Synacek Software Engineer, Red Hat
Re: FFI questions
On Fri, May 15, 2020 at 10:09 PM Taylan Kammer wrote: > > On 15.05.2020 15:47, Jan Synacek wrote: > > Hello, > > > > Currently I have something like this: > > > > (define libxcb (dynamic-link "libxcb")) > > > > ... > > > > (define c-change-window-attributes > >(pointer->procedure void > > (dynamic-func "xcb_change_window_attributes" libxcb) > > (list '* uint32 uint32 '*))) > > > > (define (change-window-attributes conn win mask vals) > > (c-change-window-attributes conn win mask (bytevector->pointer vals))) > > > > The last argument to xcb_change_window_attributes is 'const void *' and I > > need to pass a u32 vector to it. As it is right now, it segfaults when I > > try passing #u32(something) to 'change-window-attributes'. Is it possible > > to make it accept a u32 vector using just Scheme or do I have to work > > around it on the C level? > > I think the reason it segfaults might be that the #u32() object gets > garbage collected soon after you call bytevector->pointer on it. See > that you put it in a variable, and reference that variable at some point > after xcb_change_windor_attributes should be done with the vector, to > make sure that this is not the problem. > > Otherwise I'm not sure why it should segfault. A #u32() bytevector > really should be backed by a contiguous array of uint32_t values, just > like what you'll get when you define a uint32_t[] in C. This works, thanks! (define (change-window-attributes conn win mask vals) (define b (list->u32vector vals)) (c-xcb-change-window-attributes conn win mask (bytevector->pointer b))) > > My second question is about FFI and structs. Is it possible to access C > > struct members from Scheme by name? If not, how do I generally approach the > > problem? I've checked how guile-xcb does it and it seems to be building > > hash tables with field names as keys. But that basically requires me to > > "redefine" all the C structs that I would be interested in at the Scheme > > level. > > These might be useful: > > https://github.com/TaylanUB/scheme-bytestructures > > https://www.nongnu.org/nyacc/ffi-help.html > > I maintain bytestructures, am happy to answer questions. (If I don't > respond on the mailing list, feel free to mail me directly or open an > issue on GitHub; mails with guile-user@gnu.org and guile-de...@gnu.org > in the To: or Cc: fields land in a folder that I don't always check.) Very interesting, I'll take a look. Thank you, -- Jan Synacek Software Engineer, Red Hat