[Chicken-users] Redefining a macro in terms of its earlier definition
Suppose I have a macro, mac. I want to modify the expansion to expand to something along these lines: (if condition new-code old-mac) where old-mac would be an expansion of the old macro mac with exactly the same arguments. This would enable macros to be extended in a way that is compatible with their earlier definitions, without duplicating the original expansion explicitly. So I want the new macro definition to expand to code that tests for a condition and evaluates to a new value if a condition holds, but evaluates exactly the same as the old expansion if the condition is false. Let's assume I want to write the second version of mac as an explicit renaming macro. What it boils down to is that I need to capture the expansion of the old version of mac within the definition of the new one. Suppose the first version of mac is exported by module mactest1 I can do something like this: (import-for-syntax mactest1) This gives me access to the macro expansion of the old mac at macro expansion time. Now (define-syntax (mac x r c) (let ( (%if (r 'if)) (%printf (r 'printf) (%string? (r 'string?))) `(,%if (,%string? ,(cadr x)) (,%printf mactest2 ~s~% ,(cadr x)) ,(mac (cadr x) However this doesn't work because as well as expanding the old version of the macro it also executes it. The error message displays it as follows: (if39 (#%string? Hello) (printf40 mactest2 ~s~% Hello) #unspecified) (if39, printf40 and #%string? are results of the naming and are bound to the same syntax as if, printf and string?) The value #unspecified is the result of executing the expression (mac (cadr x)) within the macro expander, which is obviously not what I wanted. Without import-for-syntax, no expansion occurs because the macro expander has no knowledge of the original macro and it treats mac as an unbound variable.ᩡ Restoring define-for-syntax and quoting the internal invocation of mac, thus: ',(mac (cadr x)) is more successful, but the quoted expression is evaluated by the resulting code irrespective of the result of the if. Placing the quote inside the unquote is not good: ,'(mac (cadr x)) This seems to send the macro expander into an eternal loop, presumably trying to expand its own body indefinitely. What I need is for the expansion of the original macro to be inserted into the expansion of the new macro in the place where #unspecified appears above. Is this possible? ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Wikipedia
The Wikipedia article on Scheme had been of rather poor quality for some time and I always meant to do something about that. During the past week or so I've given it a pretty severe rewrite, and in doing so I've learned a lot about Scheme, and particularly its history, that I didn't realise I didn't know. http://en.wikipedia.org/wiki/Scheme_(programming_language) Note that the article is very strongly biased toward R5RS. I think this is in keeping with the neutral point of view principle, in which subjects are covered according to their importance. Clearly R5RS is going to be around for a good long time and is the de facto standard for all but a few Scheme implementations, whereas R6RS got off to a very shaky start and hasn't yet gained widespread acceptance among implementers; I've started, but will need a lot more time to complete, a comprehensive history of Scheme, starting with prehistory, the first block structured programming languages and the first Lisps, and eventually coming down to the present-day language. I have a lot of material for this because Geral Jay Sussman and Guy L. Steele have never hidden their pride at having produced such a gem, but it all has to be read through and digested. http://en.wikipedia.org/wiki/History_of_the_Scheme_programming_language I offer this up in the knowledge that others on this list may find it interesting, and of course any help in researching the history would always be welcome. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] http cookie order
Thanks for a very informative analysis. Of course this whole problem only cropped up because we Schemers like to build up lists by consing new elements to the front. I would probably have included a reverse in the result of the let loop without thinking, but unless you have reason to suspect that attribute order will matter somewhere down the line, that's just wasted CPU cycles and wasted consing. Of course, then somebody comes along and writes a hack to update the cookie attribute.. :) ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] http cookie order
Using http.egg to write a bot that has to login to a ubb forum, I discovered that the cookie processing order of that egg resulted in login failure. When I tweaked http:read-request-attributes to reverse the order of the attributes it returned, all was well. This is because in reply to a successful login the ubb server sends a sequence of set-cookie headers, one of which is something like ubbt_myid=deleted (presumably to end any previous session) while a later header contains a cookie that looks something like ubbt_myid=26 signifying the id corresponding to the username. Processing the cookies in the wrong order results in the Cookie attribute of the http-request object being set to contain ubbt_myid=deleted, destroying the session login data on the client side and effectively ending the session. I guess I'd recommend that we incorporate my tweak to http:read-request-attributes into the egg, but thought it best to circulate the matter widely first. Is there any reason why the attributes should be retained in the current order (legacy code that depends on the reversed order, perhaps?) If so, I guess the http:extract-cookies procedure could simply reverse the order of the set-cookie attributes before processing them. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] 2.739 build problems
This is a result of my attempt to rebuild from a copy of trunk taken this evening. I'm building on a recent install of Ubuntu Gutsy Gibbon. The underlying chicken installation (used for bootstrapping) is 2.732. [EMAIL PROTECTED]:~/Projects/Installs/chicken$ make PLATFORM=linux PREFIX=/usr/local clean make -f Makefile.linux clean make[1]: Entering directory `/home/me/Projects/Installs/chicken' rm -f chicken csi csc \ chicken-setup chicken-profile csi-static \ csc-static chicken-static chicken-bug chicken.info *.o \ libchicken.so libuchicken.so \ libchicken.a libuchicken.a \ \ chicken.info pcre/*.o make[1]: Leaving directory `/home/me/Projects/Installs/chicken' [EMAIL PROTECTED]:~/Projects/Installs/chicken$ nice make PLATFORM=linux PREFIX=/usr/local make -f Makefile.linux all make[1]: Entering directory `/home/me/Projects/Installs/chicken' /usr/local/bin/chicken library.scm -quiet -no-trace -optimize-level 2 -include-path . -explicit-use -output-file library.c gcc -fno-strict-aliasing -DHAVE_CHICKEN_CONFIG_H -DC_ENABLE_PTABLES -I. \ -c -Os -fomit-frame-pointer \ -DC_BUILDING_LIBCHICKEN library.c -o library-static.o gcc -fno-strict-aliasing -DHAVE_CHICKEN_CONFIG_H -DC_ENABLE_PTABLES -I. \ -c -Os -fomit-frame-pointer \ -DC_BUILDING_LIBCHICKEN eval.c -o eval-static.o /usr/local/bin/chicken extras.scm -quiet -no-trace -optimize-level 2 -include-path . -explicit-use -output-file extras.c -extend private-namespace.scm Error: call of non-procedure: #unbound value Call history: eval (put! var (quote c:namespace) (##sys#string-qualified-symbol prefix (symbol-string var))) eval (##sys#string-qualified-symbol prefix (symbol-string var)) eval (symbol-string var) eval (put! var (quote c:namespace) (##sys#string-qualified-symbol prefix (symbol-string var))) eval (##sys#string-qualified-symbol prefix (symbol-string var)) eval (symbol-string var) syntax(void) eval [##sys#alias-global-hook] (get var (quote c:namespace)) -- make[1]: *** [extras.c] Error 70 make[1]: Leaving directory `/home/me/Projects/Installs/chicken' make: *** [all] Error 2 [EMAIL PROTECTED]:~/Projects/Installs/chicken$ more version.scm (define-constant +build-version+ 2.739) [EMAIL PROTECTED]:~/Projects/Installs/chicken$ ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] inlining
On 9/13/07, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: Thu, 13 Sep 2007 10:56:33 +0200, Felix wrote: You must compile in block mode, or hide the procedures that you want to have inlined: a procedure can not be inlined, if it is globally accessible. Thanks, Felix. After adding the csc options -block -debug oi I can see that (and which) functions are inlined. If you still want inline procedures within your package, hide the inline versions and declare public wrapper procedures. If you want globally-inlineable procedures, possibly using include is the way to go. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] emacs editing mode for chicken ?
On 13 Sep 2007 14:55:13 -0300, Mario Domenech Goulart [EMAIL PROTECTED] wrote: Quack: http://www.neilvandyke.org/quack/ http://chicken.wiki.br/Editing%20Chicken%20code If you do use quack.el, you should perform the following edits: In ~/.emacs Add (load-file ~/quack.el) In ~/quack.el Search for Chicken User's Manual Change the url on the following page to http://galinha.ucpel.tche.br/The%20User%27s%20Manual; Change the defcustom quack-default-program command to run csi, the Chicken Scheme interpreter: (defcustom quack-default-program csi Default Scheme interpreter program to use with `run-scheme'. :group 'quack :type 'string) If you never intend to use any other Scheme interpreter from quack, you may want to edit quack.el to change the value of quack-run-scheme-always-prompts-p from t to nil (t and nl are the emacs-lisp equivalents of Scheme's #t and #f). If you leave it as it is you'll be prompted every time but the default (csi in this case) will always be accepted if you press enter at the prompt. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] Packaging libraries securely
On 8/9/07, felix winkelmann [EMAIL PROTECTED] wrote: On 8/8/07, felix winkelmann [EMAIL PROTECTED] wrote: The sandbox egg will be the only thing that gives a bit of security, but it provides only a very basic Scheme dialect and is pretty slow. The only (somewhat brute-forcish) solution that comes to mind is to compile to a static executable and hack somethhing together with rlimit and chroot(1). Do'h - to be safe you want to compile it in a chroot too - expansion/compile- time code might break as well... Thanks, Felix, and thanks also to Peter Bex for the sandbox egg suggestion. My apologies for not acknowledging the responses earlier. I've investigated chroot jail methods, and it seems to me that a solution that involves the acquisition of root by a program that doesn't otherwise need it could be a classic example of jumping out of the frying pan into the fire. If the user wants to import a rootkit, fine, but I don't want to do half his work for him! One thing I do have here is complete control over whether the program will be run, because I compile all code on my system at some point prior to running it. So I've decided to maintain a list of symbols I don't permit in the user's code. Obviously eval has to go, and with-output-to-file and the like. No foreign-lambda, foreign-code, etc, and no ##core#foreign-lambda either. The programmer doesn't need to write to, or for that matter even to see any part of, my host file system, nor to use include, though he *is* permitted to run a bespoke version of require-extension and (declare (uses)). I have written a user-preprocessor compiler extension (see http://chicken.wiki.br/Using%20the%20compiler#Extending%20the%20compiler ) that scans the source code and throws a fatal error if one of the forbidden symbols appears in the user's code. This is actually a lot less clunky than my original method. I only need to worry that I may have let through a symbol that could do some damage, and that's a lot less of a worry for me, running all my code in a dedicated user account, than the thought of having to run my code with root access so that it can use chroot. Another part of the strategy is to give each user program unit an initial empty export list ( (declare (export)) ). This makes it very difficult for the programmer to hijack the system by substituting his own code for global procedures such as string-append, apply, and so on, which would make it fairly easy to eavesdrop carelessly written library code and perhaps crack the system. The programmer must explicitly declare his exported symbols, and these can be scanned during compilation in the same manner as the other symbols--except that the list of forbidden exports would include just about every useful procedure, macro or top level variable known to chicken, as well as all symbols exported (deliberately or accidentally) by any of the eggs used by my runtime code. It may be possible to relax the restriction on eval at some point by providing a substitute for eval that performs code using the sandbox egg, so that egg could well play a useful part in the runtime system. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] Scheme-themed cloth badges?
Last time I was at Gay's the Word, which was admittedly a long time ago (well what with the wife and the kids...) there were plenty of badges of all types bearing a lambda, which has been a gay symbol for some decades now. This could cause confusion if you're heterosexual, but for gay schemers this strikes me as a way to kill two birds with one stone! ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Packaging libraries securely
This is basic stuff. I think it's a bit ridiculous that I'm asking this question so late in my project. Part of my executable, written by me, needs to do all kinds of hairy, scarey stuff with my native operating system, an external website (Wikipedia, actually), but another part of my executable is a main program written by a user, which I link together with my framework (which I call Iron Chicken). This is neat because it means the Wiki contents can easily be queried in Scheme. A typical scenario on a large wiki like English Wikipedia (getting on for two million articles) is that the user will write a program on a new page in his private page space (his userspace, to use the Wikipedia jargon). and a bot will detect this page, compile it as a Scheme program and execute it. The output is fed out to a wiki page so that it becomes part of the collaborative wiki process. The problem is that I obviously don't want random people walking up and writing a script that will be able, for instance, to send spam emails. And I don't want them to be able to open a file for writing on my local system (at least for now, until I work out how to run the Chicken program in a chroot jail.) My current approach is to compile the user script with an included preamble which redefines important stuff. For instance: (define-macro (dummy name) `(define ,name (lambda x (force (delay (begin (display (format ~a is not available~% ',name)) #f)) (dummy open-input-file) (dummy call-with-output-file) And so on. It seems to me that I need to do this otherwise just about everything in the namespace will be available at runtime, co-optable for bad stuff. Or am I just being a silly sausage? Is there a better way of doing this? ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Iron Chicken
I'm working on some bot code for wikis based on the Mediawiki engine, which powers Wikipedia. My project name is Iron Chicken. Currently I've got an egg, irnc-base (Iron Chicken base) which implements the api.php interface to mediawiki, and also enables login and editing via the usual nasty screen scraping methods. This is in the subversion repository now and will appear on the egg repository under web as soon as it's updated (provided I didn't screw up). The egg makes extensive use of sxml, so you need htmlprag and sxml-tools to use it. The sxml facility is pretty cool because api output is all in xml, and you can do amazing stuff with sxpath to navigate the output data. There is some example code. For documentation on mediawiki's api, see: http://en.wikipedia.org/w/api.php and http://www.mediawiki.org/wiki/API ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Projec mayo: a scheme sourrce level debugger for Chicken
I'm quite close to releasing a basic source-level debugger for Chicken. The first release will provide the user with a modestly enhanced GNU debugger environment. As well as the existing functions provided by gdb at C source level, the user will have the ability to load applications by their Scheme filename, list the Scheme source, and set breakpoints on those Scheme source lines that are known to the GNU debugger. In general, Scheme source lines that contain procedure calls are known to the GNU debugger because of the C_trace calls that are emitted by the chicken compiler during code generation. Source listings will show which Scheme source lines are known to the GNU debugger, and which of those have breakpoints set on them. This should enable very basic execution tracing at the Scheme source level. Access to Scheme variable bindings will *not* be available in the first release. Meanwhile I've created a project page on the Chicken wiki. mayo will be the generic name of the debugger. http://galinha.ucpel.tche.br:8080//mayo ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] mayo.egg: the first alpha release of a Scheme source-level debugger for Chicken
This is now available for use. it's basically a proof of concept, showing how gdb.egg (which is intentionally built for versatility rather than usability) can be used to construct a mapping from Scheme to C which enables an end user to debug a Chicken scheme program. This egg is capable of identifying Scheme source lines known to the debugger at the level of the C program, and enables the user to set breakpoints in the corresponding loaded binary image file and then running the program until execution is interrupted by a breakpoint or termination of execution. https://galinha.ucpel.tche.br/svn/chicken-eggs/mayo/ Login: anonymous Leave the password blank In due course an installable egg will probably show up here: http://www.call-with-current-continuation.org/eggs/mayo.html You need to install gdb.egg to use mayo. This debugger requires the successful installation of the gdb (GNU debugger) on your system. I welcome all comments on this egg, which is part of Project mayo. http://galinha.ucpel.tche.br:8080//mayo ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] SWIG and callbacks
On 3/4/07, felix winkelmann [EMAIL PROTECTED] wrote: You also have to save the callback-continuation (see generate-foreign-stubs in c-backend.scm). For the swig-specific information, you should contact John Lenz (who wrote the swig backend). Thanks. I just checked c-backend.scm this afternoon before coming online and noticed the extra code generation (and with that bit it finally begins to make sense). I've been holding Chicken's CPS model at arm's length for some time but I think I'm going to have to study it closely in order to make progress here. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] SWIG and callbacks
I'm trying to write a callback in Scheme. The unusual thing about this callback is that it's intended to be invoked during the course of a Swig call. I know that our native FFI has foreign-lambda and foreign-safe-lambda, the latter intended for this kind of circumstance. My question is: does Chicken Swig also permit this, or would I have to rewrite the swig code to make it safe for callbacks? Examining the Scheme code for create-foreign-stub, which generates all foreign calls in the Chicken ffi, it seems that what needs to be done before a safe or what was formerly known as a callback call, boils down to the following: * make 24 bytes more space for the result type * perform a minor garbage collection. I suppose I could add these to my swig-generated stubs and see what happens, but I thought I'd ask first in case somebody knows. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Passing Scheme callbacks to Swig wraps.
I've been using Swig to wrap a medium sized C++ library. Part of the task involves enabling the dynamic method pointers built into this particular class hierarchy to be manipulated by the Scheme programmer. As a concrete example, I want to enable the Scheme programmer to be able override the menubar method with a method written as a Chicken Scheme callback (define-external) procedure, by passing a pointer to that callback to the setter for the C++ class's menubar function pointer member. To do this, the Swig code at some level needs to convert the callback pointer of the method to a Swig pointer so that it can be passed to the proxy class. I suppose if I were a Swig guru I'd write a Swig typemap to do that. I'm not. Does anyone know whether that kind of thing would be possible in Chicken Swig? If not, I can still do it. I can write my own function, callable from Scheme, to take a callback pointer and call SWIG_NewPointerObj(), producing a new swig pointer object for the function pointer datatype. It would be nice to know if anyone else has experience of these issues. I'm feeling my way here. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Re: Passing Scheme callbacks to Swig wraps.
On 2/28/07, Tony Sidaway [EMAIL PROTECTED] wrote: As a concrete example, I want to enable the Scheme programmer to be able override the menubar method with a method written as a Chicken Scheme callback (define-external) procedure, by passing a pointer to that callback to the setter for the C++ class's menubar function pointer member. To illustrate, here's how I do it at present, by subclassing in C++ in my Swig interface file: class TAppScm : public TApplication { public: TAppScm( TStatusLine *(*cStatusLine)( TRect ) = TAppScm::initStatusLine, TMenuBar *(*cMenuBar)( TRect ) = TAppScm::initMenuBar, TDeskTop *(*cDeskTop )( TRect ) = TAppScm::initDeskTop ): TProgInit (cStatusLine, cMenuBar, cDeskTop) {}; }; The derived class uses a constructor with default values so I can instantiate it in Scheme with just (make TAppScm), which creates the tinyclos proxy and thereby the C++ class with the default Status bar, MenuBar and Desktop. When I use the run method for this proxy my C++ object (a use interface window) appears on the screen and behaves as expected. Hurray! The problem I'm trying to solve here is how I substantiate the class with a menubar coded as a C++ callback. The class hierarchy in question, by the way, is Borland's rather good Turbo Vision text-based user interface library, which I recently discovered is now part of a pretty good open source project. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] New user-interface egg: slang.egg
S-Lang (also known as slang or SLang, I'll call it slang from now on) is a very well established, well supported, text-based user interface. John E. Davis used slang to produce his slrn Usenet newsreader and the JED text editor, and the mutt mailer and lynx web browser also use slang's display routines. Slang's display routines are somewhat simpler than ncurses, but I think they benefit from that. They're pretty reliable and easy to use. Their use in a number of popular and reliable free software products shows that it's a popular choice for programmers. I've wrapped many of this library's display and keyboard control routines in a new egg, slang.egg. Obviously you need to install Slang to use it: http://www.s-lang.org/ There isn't much in the way of documentation yet, but I've written an adaptation of the pager.c example and placed it in the slang-examples directory that is distributed with the egg. This is part of my project to produce a source-level debugger for Chicken. Rather than choose a graphical user interface which would lock out a lot of potential users, I'm going for the lowest common denominator. Any system that can emulate a VT100 terminal should be able to run a program that uses the slang library, it's fairly easy to install and needs no special configuration. I plan to write the debugger display system to use a plugin display module, so that the same debugger can be adapted to many different user interfaces, whether graphical of textual, with their own representations of the same basic information. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Problem mapping to unsigned char *
The nearest thing we have for mapping unsigned char * is c-string, but using that interface makes a compiler complaint of the following type: slang.c:1254: warning: pointer targets in passing argument 1 of 'SLang_buffer_keystring' differ in signedness This is just a niggle, really, because it will probably never have a serious problem, but it would be nice to have a workaround for this. unsigned-c-string? ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] Problem mapping to unsigned char *
On 2/26/07, John Cowan [EMAIL PROTECTED] wrote: Actually, it's architecture dependent whether char is a synonym for signed char or for unsigned char. Rather than complicating the interface, I'd rather live with the gcc warning. Yes, you would want to use c-string without a sign qualification if the sign is to be decided by the compiler. It's when the programmer makes a choice (presumably because it matters at some semantic level or other) that I'd suggest that the foreign interface should permit us to follow that choice (just as it provides signed and unsigned qualifications for scalars). I don't mind living with it as long as people who build software from my eggs don't mind living with the warnings from an otherwise clean build. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Safe interrupt handlers?
An interrupt handler written in Chicken Scheme probably can't do a lot without knocking over a heap of dominoes. Nevertheless, would a simple lambda that only changes a top level flag variable be stable enough to be useful? This is often all that posix interrupt handlers written in C do anyway. This is the sort of thing I'm thinking of. When the interrupt is fired, procedure sigX is executed irrespective of the current state of Chicken. The following should be read as pseudocode rather than a skeleton for actual implementation. (define (sigX-flag #f) (procedure (sigX-handler) (set! sigX-flag #t)) (procedure (handle-sigX) (with-interrupts-disabled (lambda () (do-some-stuff) (set! sigX-flag #f (set-sigX-handler-to-handle-sigX) (let loop ((...)) (if sigX-flag (handle-sigX) (begin (do-something-else) (loop ...))) ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Re: Safe interrupt handlers?
To clarify my earlier post, procedure sigX-handler should be executed when the interrupt fires. The procedure handle-sigX is executed by the program when it polls the signal flag and finds it in a set state. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] swig and c++ and stuff
I tried a big SWIG wrap on part of a C++ library. This generated a .cxx wrap file and a .scm file. The build sequence I'm using is this: $(CHICKEN) tvision.scm -output-file otvision.c $(CXX) --shared otvision.c tvision_wrap.cxx -o tvision.so `rhtv-config --include` `rhtv-config --cppflags` `rhtv-config --dir-libs` `rhtv-config --dlibs` -lchicken This seems to build to a tvision.so file, but when I install that and (use tvision), I get this: ersion 2.524 - linux-unix-gnu-x86 - [ libffi dload ptables applyhook cmake ] (c)2000-2007 Felix L. Winkelmann ; loading /home/me/.csirc ... ; loading /usr/local/lib/chicken/1/readline.so ... ; loading library regex ... #;1 (use tvision) ; loading /usr/local/lib/chicken/1/tvision.so ... Error: (load) unable to load compiled module /usr/local/lib/chicken/1/tvision.so /usr/local/lib/chicken/1/tvision.so: undefined symbol: _ZN6TGroup7matchesEP5TView Call history: syntax(use tvision) syntax(##core#require-extension (quote tvision)) syntax(begin (begin (##sys#require (quote tvision))) (##core#undefined)) syntax(begin (##sys#require (quote tvision))) syntax(##sys#require (quote tvision)) syntax(quote tvision) syntax(##core#undefined) eval (##sys#require (quote tvision)) -- I'm a bit new to Swig wraps. Is this a common problem? If so, what have I done wrong? ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] swig and c++ and stuff
On 2/26/07, felix winkelmann [EMAIL PROTECTED] wrote: The missing symbol is strange, though. Check the _wrap.cxx file and the binaries with nm (and c++filt genRefs() only appears as a friend function in the class prototypes; it isn't implemented so it doesn't belong in the wrap. I removed it and another class function that wasn't implemented, and now it loads fine. I can use the introspection procedures of tinyclos to look at the slots and methods. I suspect that any remaining problems are due to my inexperience with tinyclos. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] gtk2 and gtk2-gobject eggs, release 0.3
I've just committed gtk2-object.egg and gtk2.egg releases 0.3. Later on I'll probably commit gtk2-glade.egg 0.3. The frequent crashes are a thing of the past; this is stable code. I'll declare a beta release when I've resolved some build issues and obtained (or produced) a maintainable version of Tony Garnock-Jones' documentation. gtk2-gobject.egg by itself provides bindings for gtk's object oriented type system. It's possible to use gobject to implement introspective object oriented-applications in C. gtk2.egg provides gtk support and requires gtk2-gobject. gtk-glade.egg will provide libglade support and requires gtk2.gobject. The glade egg won't require gtk2.egg because it is possible to write Chicken programs that don't depend on on gtk2's Chicken bindings--you could for instance write all your signal handlers in C. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] New tool: patch.egg
This is a tool for producing and performing software patches, inspired by the patch program by Larry Wall and Paul Eggert. It provides procedures to produce patches, apply them and reverse them. It depends on the posix extension, and to produce patch files you will first need to produce GNU diff output of the patch. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Simple GUI features
While it may be rather difficult, and possibly even impracticable, to produce a general super GUI, it should be possible for all Chicken GUI eggs to provide GUI features in a uniform way. To show the kind of thing I'm thinking of, I'll give some examples, graded by level of complexity. It isn't intended to be a definitive list, only an illustration of the kind of interaction that would make Chicken useful for basic scripting on a GUI-based system. The functions would enable simple interactive Scheme programs to make use of available facilities in any available graphical user interface. I would also suggest that these features could be provided by default on any chicken build where the underlying operating system supports a GUI that is known at build time. Level 0: These basic functions are to be defined by any GUI egg compliant with this suggestion. The egg must register the feature 'gui-0, so that programmers can use cond-expand and default to non-GUI interaction where the feature is not provided. Function: (confirmation-dialog MESSAGE) Displays a message string and accepts a confirmation or cancellation. It returns #t if the user confirms (eg: clicks an OK button) and #f if he cancels (eg: clicks a Cancel button). The appearance and precise behavior of the widget is to be left to the implementor, and should follow the conventions of the underlying GUI where possible. It is an error to provide a non-string MESSAGE or one consisting of the empty string, or one that is longer than 256 characters. Function: (string-request MESSAGE [DEFAULT [MAX-CHARACTERS]] ) Displays a message string and accepts a string which is the return value of the function. If a default is given, the message-string widget is preloaded with that string value, otherwise it is initially empty. If no MAX-CHARACTERS value is given, a sensible default may be chosen, but at least 512 characters must be accepted. There should be a way for the user to cancel the request, in which case the return value is #f. It is an error to provide a non-string MESSAGE or one consisting of the empty string, or one that is longer than 256 characters. It is an error to provide a non-numeric MAX-CHARACTERS, or a value less than 1 or greater than the implementation maximum (which must be at least 512 characters). Level 1: These more complex functions are to be defined by some GUI eggs compliant with this suggestion. The egg must register the feature 'gui-1, so that programmers can use cond-expand and default to non-GUI interaction where the feature is not provided. Function: (text-edit MESSAGE LIST) Accepts a list of strings which are displayed and may be edited by the user. The facilities must permit deletion and insertion of the whole text, whole lines, and arbitrary regions of text including single characters. Other features of the underlying GUI may be supported at the discretion of the implementor. There must be a facility for the user to terminate the edit at any time, in which case the function returns #t if there has been no change, or else a new list of strings representing the edit contents. There must be a facility for the user to cancel the edit at any time, in which case the function returns #f. It is an error to provide a non-list, or a list containing anything other than strings. The null list may be provided, in which case the initial contents of the edit widget will be blank. MESSAGE is mandatory and is subject to the same constraints as in the gui-0 functions. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] gtk2.egg
On 2/13/07, Andre Kuehne [EMAIL PROTECTED] wrote: Tony Sidaway wrote: [...] The main part of the code is a pretty straightforward wrap of libgtk2 and libglade. The only unusual thing is that a bespoke wrap program is used instead of SWIG, and relies on defs files that are published by the (Python) PyGTK project. I have no experience with writing glue-code, just curious. What's the advantage over SWIG? Does this approach make it easier to stay compatible with new gtk versions, since PyGTK is guaranteed to be? SWIG is excellent, but it's an automated tool and has limitations. For instance SWIG is unlikely to be able to reconstruct the object structure of the library components because the code is C and the underlying object definitions are partly a matter of coding convention and partly due to GTK+'s runtime object support system, gobject, of which SWIG understandably knows nothing. I inherited the wrapping code from Tony G, and he seems to have done an excellent job of capturing the object semantics, partly because they are encapsulated in the PyGTK definitions which are used to guide the wrapping process. By the way I'd forgotten that there is actually a very good manual to this egg in the doc directory. I've decided to split off the gobject part of the library, and the glade part, each into its own egg. The Glade code doesn't have any dependencies on the gtk binding, so it's perfectly possible to have a working Glade application in Chicken with only the gobject egg and the glade egg. Glade also has a lot of potential in Scheme because its object model is XML, and Scheme + sxml + Glade would probably make a very good GUI scripting toolkit. Other candidates for splitting off are gdkevent (low level event support) and gdk itself (drawing kit). There is also the possibility of splitting the GTK code into basic. intermediate and advanced modules. I'd have to satisfy myself that basic and intermediate modules would be useful for producing real code, but there is also an impetus here to make the huge wodge of code more manageable, as well as reducing installation time. The gobject code, for instance, takes a few seconds to install on my system, and I would like to produce a basic install for gtk that took a comparable amount of time, so that the programmer evaluating this egg could download and run example code casually before committing himsel to a long egg install to get at the juicy stuff needed to produce advanced Scheme GUI code. Attached is a drop-in-replacement for extract-all-types. Thanks. I've been away from the net for a couple of days and I also wrote a replacement in Chicken. Additionally the script excludes gdk_window_get_type. Otherwise i get this compile error: I think I need to work on the wrapping. The egg should perhaps contain a master file containing information merged from all defs files, with information about how the functions have evolved. Only those definitions pertaining to the GTK version we're building for should be selected during a particular build. In my working copy I've hand-coded some of the NULL-sentinel varargs functions, but wrap.scm should be fixed to take care of this itself. The functions in question are well flagged in the header files (at least for recent versions) although not in the defs files. Besides the error mentioned above, it compiles against my gtk+ 2.10.6. However most sample-apps crash: Yes, it's early days. It's good news that it seems to be close to working on recent releases of GTK, but we have to live with the fact that many installed Gnome systems are built on top of GTK releases that are somewhat behind the cutting edge, and I myself would hesitate to rebuild the foundation of my Gnome system's GUI, lest something break and I end up with no GUI for a while. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] gtk2.egg
$ svn co https://galinha.ucpel.tche.br/svn/chicken-eggs/gtk2 (login anonymous, leave the password response empty) This may be of interest to GUI enthusiasts. The interesting part of the code, to me, is what is built on top of the wrapped library. g+ is a very clean, Scheme-like GUI library that keeps the fussiness of the underlying C implementation well away from the Chicken code. Here for instance, in g+, is a GTK OptionMenu object containing an embedded button and a nested menu, with the signal handlers embedded in the menu structure. (g+option-menu (g+menu (g+menu-item First (g+signal 'activate (lambda (i) (print Chose 1 (g+menu-item* (g+button Hello (g+signal 'clicked (lambda _ (print Why, hello! (g+menu (g+menu-item hi1 (g+signal 'activate (lambda (i) (print Chose 2 (g+menu-item hi2))) (g+menu-item Third (g+signal 'activate (lambda (i) (print Chose 3)) This is an egg from code originally produced by Tony Garnock-Jones (tonyg) in 2002. The code rotted a bit over the years, and I spent a few days in January cleaning it up so it builds and runs on my Ubuntu system. Tony G responded to my licensing request yesterday and permitted me to upload the updated code. I've packaged it as an egg. The main part of the code is a pretty straightforward wrap of libgtk2 and libglade. The only unusual thing is that a bespoke wrap program is used instead of SWIG, and relies on defs files that are published by the (Python) PyGTK project. This egg is NOT related to the gtk egg produced by Alejandro Forero Cuervo and Manuel Alejandro Cerón Estrada. That other project was based on SWIG bindings and seems to have stalled. There are issues with this egg as it stands at present. It is definitely not usable for anything serious yet. Firstly, libgtk+ is absolutely huge and this is an attempt to wrap it all. The build process is an absolute beast and takes ages to run on my system. It should probably be split up into bite-sized chunks. There are UNIX dependencies in the build process, most notably the shell script extract-all-types which really should be converted to chicken. There are also probably some strong gtk-2.0 version dependencies. It builds on my Ubuntu system with Ubuntu's stock gtk 2.8.20 build. It also expects libglade. I cannot make promises about which other versions of GTK it will run on, and if you want to build it without libglade support you'll have to tweak the code a bit. The wrapping system doesn't correctly handle variable argument lists with a NULL sentinel, despite the gtk headers signalling the usage clearly. Some of the demo programs fail mysteriously. Tony G and I think it's a pointer wrapping problem, and I'll be working on fixing that. Further bug reports would be most welcome. Please include details of your system and the version of libgtk you're using. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] GUI: thoughts on practicality.
It's been my feeling for some time that it should be possible for a Scheme programmer to create windows with menus, buttons, and whatnot, with a reasonable expectation that the details of implementation can be left to low level drivers. Furthermore, the Scheme programmer should be able to write simple code to do simple things. The code should be simple but the implementation can be complex. At the high level I don't care whether the widget I'm handling is written in C, C++, Java, Common Lisp or Scheme. I don't want to have to care whether my code is running on native Windows, Cygwin, X, Macos or a cellphone GUI. I don't want to have to care whether the rendering library is Cairo or SDL. These are inconsequential fripperies and unwanted dependencies that, if I let them, will seal my code into a tomb as the years go by. So it seems to me that the way to produce really good, durable and reliable Scheme code for GUI programming is to concentrate on a good high level design. What I suggest here won't satisfy the requirements of game designers, or programmers who think the GIMP needs to be rewritten in Scheme, and it might even fall short of what most people would expect of a modern GUI. This is because I think we already have enough Window managers, skin systems, game toolkits and the like, and nearly all the successful ones are written in a low level language. Rather than duplicate that work, these suggestions are intended to enable a Scheme programmer to write an event-controlled, graphical user interface so that he can communicate with the user in a way that the user finds intuitive. and to do so without tying him to a particular brand of GUI. Eventually I will have to wade deeply into all the popular GUI designs and come up with one that describes the basics of all of them to a level of detail that would be useful to a high level programmer. But for now I'll list some of the things that I think are required in a useful high level GUI design for Scheme. * Geometry: the dimensions of each display device must be available to the high level program. Both pixels and if physical dimensions. ** If the latter are not available to the driver, it should provide intelligent estimates and say so. ** The dimensions of GUI objects controlled by the program should be the size requested by the program, or a reasonable approximation thereof. * Color: a reasonable level of color control must be provided. * Time: the time of each event must be available to the high level program in a usable form. srfi-18? * HIgh level event handlers. a Scheme closure may be assigned to handle any event or bundle of events the program is interested in. * High level containers: there must be a way of expressing a hierarchical relationship between widgets. This should be coupled to the container mechanism of the underlying GUI where possible, but should not depend on such a mechanism existing. * Configuration: the application must be reasonably configurable at run time. The native configuration tools should *usually* take precedence, and the high level GUI works within the constraints set by those tools. The program *may* be permitted to break this. Desirables: * Queues: we need a standard for queues. whether based on Chicken, Scheme48, Gauche or whatever. High level event queues would be based on that standard. * Time: the external form of this should follow IETF RFC 3339 and any superseding standard. * Foreign function interface. A reasonably abstract foreign function interface should be provided to enable drivers to be ported from one Scheme implementation to another. Adherence to that ffi should not be mandatory. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] GUI: thoughts on practicality.
On 2/8/07, minh thu [EMAIL PROTECTED] wrote: So in your conception, accessing the event queue must be explicitly possible ? Usually, you can just provide a callback and wait for the system call it. A translating dispatcher might be used for implementation, basically a bit of glue code that listens to the native queue and translates to a standard format, and for some higher level features such as intercomponent communication a queuing system would be a good feature. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] GUI: thoughts on practicality.
On 2/8/07, Brandon J. Van Every [EMAIL PROTECTED] wrote: minh thu wrote: Again sorry for my 'random' (Brandon would call it 'insane' :) ideas... Ideas aren't insane. The labor of refactoring for multiple platforms is insane. I think people don't realize how little labor they're working with in open source. I agree here. The best hope of something sustainable coming about, in my opinion, is for a number of people to come up with their own code and work hard until they convince themselves that their own version isn't as workable as the other chap's, then they all get behind that design and push to make it work. The winning design would probably be good at doing simple stuff and lousy at doing complicated stuff, but would be better than what we have now: essentialy nothing. It might be amusing to frame a GUI project as a challenge to Gambit or Bigloo programmers! :) ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] GUI: thoughts on practicality.
On 2/8/07, Brandon J. Van Every [EMAIL PROTECTED] wrote: Tony Sidaway wrote: It might be amusing to frame a GUI project as a challenge to Gambit or Bigloo programmers! :) I threw down the gauntlet to the Steel Bank Common Lisp crowd a number of months back. I said their Windows build was lousy, and that we were a year ahead of them. I haven't checked on them lately. I hope I don't have to eat any crow? Be careful who you challenge, you might have to live up to it. Chicken's build is, I agree, something to boast about. But if somebody working on Gambit or Bigloo produces a really good GUI for Scheme, I'll be happy to eat crow! ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] Evicted objects
On 2/6/07, felix winkelmann [EMAIL PROTECTED] wrote: On 2/6/07, Tony Sidaway [EMAIL PROTECTED] wrote: My expectations are obviously wrong. What's happening there? Since Scheme strings do not have a zero-terminator, the call to getmem will receive a copy of the string, with a 0-terminator appended. Thanks, it's all blindingly obvious when you put it like that! So c-string arguments are never safe for use with a function that will store the pointer value for later use. To pass the String object directly, use the foreign type specifier `scheme-object' (and access the data-portion of the block via C_c_string(x), for example). Thanks. It's very obvious what needs to be done when I understand how the c-string foreign argument specifier works (which is not at all how I thought it did). I'm happy to say that my code now works. I do something like this: # static C_char *new_c_string (C_word s) { C_char *s1; C_char *p; C_word len; /* Return NULL if we're given something stupid */ if ((s C_IMMEDIATE_MARK_BITS) || (C_header_bits(s) != C_STRING_TYPE)) return NULL; s1 = C_c_string(s); len = C_header_size(s); p = (C_char *)C_malloc(len+1); /* Don't try to populate if the allocation failed */ if (NULL != p) { C_memcpy (p, s1, len); p[len] = '\0'; } return p; } # (define new-c-string (foreign-lambda c-pointer new_c_string scheme-object)) The new procedure (new-c-string OBJ) here creates an unmanaged C string from a Scheme string. And for memory management purposes I can put this new string object into the list of c-strings for the enclosing object c (which happens to be a tinyclos class instance) so the object's finalizer can return them all to the C heap by this: (use lolevel) ... (map free (slot-ref c '%c-strings)) ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] idiomatic/usual way of file-based configuration in Scheme
On 2/6/07, minh thu [EMAIL PROTECTED] wrote: It would just amount to read a list of key/value pairs in Scheme syntax. Or maybe a triple if the type is given. What do you use ? As I think you realise, this is a capability that is as old as Lisp itself. A property list is just a specialized form of s-expression. I'm not aware of any formal standards for this, but it's pretty much a matter of basic Scheme. Key-value tuples as given by other respondents ((locale ca)(lang fr)(user-data paul users)), use read to read the list of key-value pairs, (with-output-to-file properties write to write it. (define property-list (with-input-from-file properties read)) ... (with-output-to-file properties (write property-list)) And to perform lookup, (let ((value-list (assq 'locale property-list))) ...) Your first value would be (cadr value-list), the third (caddr value-list) and so on. (car value-list) holds the matching lookup key. An alternative would be to use lists of pairs ((locale . en)(lang . fr)). The only difference is that you use cdr to address the value, not car. Remember that '(a b c) is exactly the same as '(a . (b c)), so you can mix both notations in the same list as long as your software (and anyone who edits the list by hand) knows which form to use for a given property. To update, use something like this: (define my-age 64) ... (let ((value-list (assq 'age property-list))) (set-cdr! value-list (list my-age))) To delete an entry, use SRFI-1 delete or delete! (normally you'd use eq? as a comparison operator for this, to compare by keyword). (delete! 'lang property-list (lambda (key value-list) (eq? key (car value-list If your keys can't be represented as symbols, surround them in string quotes and use assoc rather than assq. An association list can contain any serializable Scheme data, including other association lists. For very large collections of keyed data that you will need to lookup frequently, consider using SRFI-69 hash tables for the internal representation. Procedures alist-hash-table and hash-table-alist are provided for this purpose. This kind of heavy duty tool shouldn't be needed for normal property lookups, however. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] What happens to a (non-simple) Scheme object sent to a foreign function?
On 2/5/07, felix winkelmann [EMAIL PROTECTED] wrote: Another option would be to create a GC root (CHICKEN_new_gc_root) and keep it on the C-side (you have to pass the argument string as a scheme-object, then create the GC-root from it). Later, you can access the gc root (CHICKEN_gc_root_ref) and use the string. The gc root will be updated on every garbage collection. You just have to make sure you free it eventually (or just reuse it). I may try that, but at the moment I've opted for a solution managed on the Scheme side. It's something like this (in tinyclos) (define-method (curl-evict (c curl) name) (let* ((obj (slot-ref c name)) (evictee (object-evict obj))) (slot-set! c '%evictees (cons evictee (slot-ref c '%evictees))) evictee)) The slot %evictees is initially an empty list, and grows with each eviction so that I can keep a tab on all objects formerly belonging to the item that have been evicted. The finalizer for the curl object is simply: (define (curl-finalize! c) (map object-release (slot-ref c '%evictees))) So now if I need to pass a string parameter to C I do this: (case type ... ((c-string) (curl-easy-set-option-c-string! rc key (curl-evict c name))) ... ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] Re: object-evict, string ports, safe-foreign-wrapper, foreign-primitive, Cheney on the Victoria Line, etc (was: What happens to a (non-simple) Scheme object sent to a foreign funct
On 2/5/07, felix winkelmann [EMAIL PROTECTED] wrote: sufficiently big). An alternative is to create a suitably sized byte-vector beforehand (in Scheme, using the heap) and copying the data inside a block of foreign code (or use move-memory!). Ah! I didn't know move-memory existed. This is probably exactly what I need. As you suggest I can create the type of object I need and just copy the raw data block into it, with the caveat that the byte order of data received from a remote source may not be as expected. No need to play limbo with the nursery. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
Re: [Chicken-users] cross-platform gui toolkit
I'm considering the pros and cons of this, but I am with Felix in the belief that a simple, Schemish basic GUI layer design is desirable. It shouldn't require Qt or Gtk, which are both on the heavy end of GUI toolkits. Instead it should provide a layer that works on top of whatever GUI tools are available, with a minimum of back-end glue code. I'm fairly new to Chicken development (though not to Scheme) and I'm making an effort to gain experience in designing extensions and tinkering with the engine. My aim is to gain enough experience to be able to contribute to the production of a GUI of this kind. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] object-evict isn't working as expected.
What's up here? I have a Scheme string that I want to send to a C library. The library will remember its location and so I want it to be in static memory, so I use object_evict and send the result of object-evict to the library as a c-string argument to a foreign-lambda. The library now knows the address of the data in the evicted string. At some point I call another library function as a foreign-safe-lambda. During the course of executing that function it executes a callback whose address I've sent it as a c-pointer argument to another foreign-lambda. The callback seems to execute okay. It makes a new u8vector and copies some data into it, then has a let loop to convert u8s to char (integer-char) and display, character-by-character However the evicted string seems to be trashed. It now contains garbage. I wondered if I could duplicate this so I wrote a simple dummy copy of the library functions. The dummy version of the first C function stores the c-string in a static pointer to char. The dummy version of the second C function executes the callback and then writes out the value of the string. The string in the dummy copy is corrupted just as it was in the real library. Further tests show that the corruption appears after the callback is invoked. Making all foreign-lambdas into foreign-safe-lambdas doesn't make any difference. However the evicted variable seems to be quite okay on the Scheme side. This is what is really puzzling. It seems that the evicted object has moved around after being evicted, and Scheme keeps track of it. But of course C doesn't know this and gets corrupted data. That doesn't make sense. If we can say one thing about the output of object-evict, surely it's that it won't move around? ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Evicted objects
This is the crux of it. $ cat testevict.scm (use lolevel) (define (myalloc size) (printf Requested ~S byte\n size) (let ((obj (allocate size))) (printf ~S\n obj) obj)) (define getmem (foreign-lambda* void ((c-string ptr)) printf (\ptr = %p\\n\, ptr);)) (define s A string) (define e (object-evict s myalloc)) (getmem e) $ Notice that I'm using the optional second parameter to object-evict so that I can print out the allocated pointer address. When compiled and run I'd expect this program to show that the pointer received by getmem is very close to the pointer returned by allocate (just the same plus the size of the header used to describe the object to Scheme, basically). Instead I get completely different values. $ csc testevict.scm $ ./testevict Requested 12 byte #pointer 0x806b488 ptr = 0xbfec0864 $ My expectations are obviously wrong. What's happening there? ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] object-evict, string ports, safe-foreign-wrapper, foreign-primitive, Cheney on the Victoria Line, etc (was: What happens to a (non-simple) Scheme object sent to a foreign function?)
On 2/4/07, Thomas Christian Chust [EMAIL PROTECTED] wrote: Tony Sidaway wrote: I'm sending a Scheme string to a foreign (C) library as a c-string. I also send it the address of a Scheme procedure created as define-external--this address is sent as a c-pointer. [...] Hello, the address of the C function wrapping the define-external'ed Scheme procedure is unproblematic, because it will never change. The pointer to the C string data may become invalid, though, once the program returns from the library call. In order to make this safe, you would have to duplicate the string in the C heap (for example using strdup) or you would have to create a non-garbage-collected copy of the Scheme string (for example using object-copy) to pass that to the library routine. In either case you would have to release the string data later on when it is no longer needed. Thanks. Would object-evict achieve the same end? I did try that but the result was that my callback function received a corrupted string, which suggests that I was probably doing something else wrong. I think at that stage I'd forgotten to declare a procedure as safe-foreign-lambda so the callback might have been executing in a rather odd closure.. For management purposes, I suppose I could tie the non-garbage collected object (constructed using object-copy or whatever) to other related resources by wrapping them all in a record (either SRFI-9 or chicken) and establishing an appropriate finalizer for the record using set-finalizer! This would free the relevant non-managed resources. The string argument I mentioned in my earlier email was being used as a key to a SRFI-69 hash table into which character or binary output from the library callback was to be accumulated in successive callbacks. The library is libcurl and the callbacks are intended to do something analogous to 1. Tell library the FILE* to which to write data received from the URL as a result of a curl_easy_perform 2. (Optional:) provide a C function to take the place of the default writer, which writes successive chunks of data to the file. The libcurl API permits the handle passed in step 1 to be an arbitrary C pointer, and it's up to the function provided in step 2 to interpret it correctly. Passing an unmanaged FILE* object (such as (foreign-value stdout c-pointer)) in step 1 works fine with libcurl's built-in writedata function but does not exploit the versatility of the API and certainly wouldn't fulfil the reasonable needs and expectations of the Chicken programmer, who would often want to have the option to have all received data passed to a Scheme variable via a string port or other suitable mechanism. Although the data may be built up in batches though several successive invocations of the callback, this all takes place in the course of a blocking call to curl_easy_perform(), so the operation is synchronous. I've decided to adopt an alternative, more scheme-like strategy that also fits the general spirit of the C implementation. Instead of file pointers or hash keys, I could use ports. This is semi-okay, but of course ports can mutate due to file access so just passing a non-managed copy to libcurl wouldn't be a good idea. Using file descriptors (port-fileno) would make assumptions about the port implementation which break down when, for instance, string ports are used. My current thought is this: In step 1, I pass the library a key (in static memory, not heap) which I associate with the port (I place the actual port in a srfi-69 hash table under that key). On receiving the key, in stage 2, my write procedure (which would ideally be written in Chicken as a safe-foreign-wrapper procedure) would pick the port out of the hash table using that key, and write the string using a method compatible with Chicken's port mechanism. At its simplest, this is (display str port). This is compatible with string port procedures such as (with-output-to-string THUNK), and so Scheme programmers would get what they expect using a mechanism they understand well. The default behavior would be to write the received character data (say, from a http get) to (current-output-port). The programmer may provide an alternative port or may redirect (current-output-port) to a string port or any other kind of port. There are still potential problems with this, that the information received may be binary rather than characters, and that the encoding may not be compatible with Scheme's. With transmitted binary there may also be the usual endian problems I'll worry about those problems when their turns come. Another problem that it would be helpful to have advice on is how to cast or coerce arbitrary data received in a Chicken safe-foreign-wrapper. Say I receive a foreign c-pointer to some data and a couple of parameters nmemb and size that when multiplied together tell me the number of bytes in the foreign object, it would be nice to have a Schemish way of converting that into a SRFI-4
[Chicken-users] Re: object-evict, string ports, safe-foreign-wrapper, foreign-primitive, Cheney on the Victoria Line, etc (was: What happens to a (non-simple) Scheme object sent to a foreign function
On 2/4/07, Tony Sidaway [EMAIL PROTECTED] wrote: Another problem that it would be helpful to have advice on is how to cast or coerce arbitrary data received in a Chicken safe-foreign-wrapper. Say I receive a foreign c-pointer to some data and a couple of parameters nmemb and size that when multiplied together tell me the number of bytes in the foreign object, it would be nice to have a Schemish way of converting that into a SRFI-4 u8vector of size (* nmemb size). I've examined locations and locatives, but those don't seem to help with that particular problem not least because there is no underlying Scheme data object, only a random bin containing binary bits whose significance is completely unknown to Scheme. Would it be best to write something to do that in C as a foreign-primitive? Basically a C function, declared foreign-primitive, that takes a C-pointer and an int, and allocates a byte vector of the appropriate size. Presumably this would eat into the nursery until such time as a minor garbage collection takes place. I suppose I mean something like this: (define produce-byte-vector (foreign-primitive scheme-object ((int size) (c-pointer data)) C_word *p = C_alloc(sizeof(C_header)+C_align(size));C_return(C_bytevector(p, size, data));)) I expect I've got the arithmetic wrong, but this is the basic idea. This is a nice easy implementation because you can then use (byte-vector-u8vector), (byte-vector-s16vector) or whatever you want to coerce the resulting byte vector to whatever you want. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] What happens to a (non-simple) Scheme object sent to a foreign function?
I'm sending a Scheme string to a foreign (C) library as a c-string. I also send it the address of a Scheme procedure created as define-external--this address is sent as a c-pointer. Later on I call a safe-foreign-lambda which will use the Scheme function whose address I sent it as a callback, and one of the arguments will be the c string I sent it earlier, which is otherwise untouched by the library code. I have no control over the C code--it's a third party library. Is this safe? Is there a risk that the c-string I passed to the library will become stale through garbage collection? It seems to work but maybe that's just by luck rather than good planning. I guess the pointer to the define-external procedure will be okay. Is there a better, safer way of doing this? ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] read-lines bug and a suggested bug fix
(read-lines [port [MAX]]) is supposed to read up to MAX lines from the port. Here's an oddity: $ cat test-read-lines.scm (define lines-per-read 5) (let loop ((lst (read-lines (current-input-port) lines-per-read))) (if (null? lst) '() (begin (map (lambda (x)(display x)(newline)) lst) (loop (read-lines (current-input-port) lines-per-read) $ cat test-read-lines.input Line 1 Line 2 Line 3 Line 4 Line 5 Line 6 Line 7 Line 8 Line 9 Line 10 (etc) $ csc test-read-lines.scm $ ./test-read-lines test-read-lines.input test-read-lines.output $ diff test-read-lines.input test-read-lines.output 6d5 Line 6 12d10 Line 12 18d15 Line 18 24d20 Line 24 30d25 Line 30 Thus (read-lines) appears to silently consume the line following the final successful read. Let's look at the definition of (read-lines). It's in extras.scm. There's some mucking about to read the parameters and whatnot, but the core of the procedure is this: (define (doread port) (do ([ln (read-line port) (read-line port)] [lns '() (cons ln lns)] [n (or max 100) (fx- n 1)] ) ((or (eof-object? ln) (eq? n 0)) (reverse lns)) ) ) The body of the iteration is as follows: Evaluate to #f unless ln is the eof object or n is 0. Evaluate to the reverse of lns if ln is the eof object of n is 0. The problem appears to be that if n is 0 and ln (which is bound to the value of (read-line port)) is not the eof-object, its value is discarded. To fix this bug, the case where n is 0 and lns is not the eof-object could be treated separately by evaluating (reverse (cons ln lns)) instead of (reverse lns) in that case. Thus I suggest that the last line of the procedure (doread) above could be replaced by: ((if (eof-object? ln) (reverse lns)(or (eq? n 0)(reverse (cons ln lns) ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Re: read-lines bug and a suggested bug fix
On 1/30/07, Tony Sidaway [EMAIL PROTECTED] wrote: Thus I suggest that the last line of the procedure (doread) above could be replaced by: ((if (eof-object? ln) (reverse lns)(or (eq? n 0)(reverse (cons ln lns) Sorry that should be ((if (eof-object? ln) (reverse lns)(and (eq? n 0)(reverse (cons ln lns) The second reverse invocation must be evaluated only when n is 0. ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Re: read-lines bug and a suggested bug fix
1. I really should test things. 2. I don't use the (do) form in my coding and it shows. 3. The following fix has been tested on the sample data. ((if (eof-object? ln) (reverse lns)(or (eq? n 0)(reverse (cons ln lns) ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Re: read-lines bug and a suggested bug fix
Nope. This is what I meant to post. ((or (eof-object? ln) (eq? n 0)) (if (eof-object? ln) (reverse lns)(reverse (cons ln lns ) ) ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] easyffi and gtk
I'm trying to do basic stuff with easyffi and gtk. Just some basic sanity checks. A very simple program that instantiates a toplevel window and terminates. $ cat window.c #! #include gtk/gtk.h # (g_type_init) (gtk_window_new GTK_WINDOW_TOPLEVEL) Compilation: $ csc -v -X easyffi window.scm -C `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0` /usr/local/bin/chicken window.scm -output-file window.c -quiet -extend easyffi gcc window.c -o window.o -c -DHAVE_CHICKEN_CONFIG_H -Os -fno-strict-aliasing -Wall -Wno-unused -Wno-uninitialized -fomit-frame-pointer -DC_ENABLE_PTABLES -I /usr/local/include -I/usr/local/include/cairo -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include rm window.c gcc window.o -lchicken -o window -L/usr/local/lib -Wl,-R/usr/local/lib -L/usr/local/lib -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXfixes -lpango-1.0 -lcairo -lX11 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -ldl -lm -lchicken rm window.o Run it: $ ./window Error: unbound variable: g_type_init Call history: window.scm: 4g_type_init-- Hmm, what am I doing wrong, here? ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users
[Chicken-users] Chicken on Wikipedia
I wrote this stub article a couple of days ago and it has expanded somewhat today. http://en.wikipedia.org/wiki/Chicken_Scheme_compiler I've concentrated on the design, which I think is the most remarkable thing about Chicken. To support this I also created an article on the garbage collection scheme that is used by Chicken, the Cheney algorithm. Things that would probably *not* fly well on Wikipedia: command line options, blow-by-blow accounts of unique features, etc. People can get that from the manual. Imagine you're a person with an interest in computer science, or a generic Lisp programmer, or just a person of high curiosity who is willing to do his own research, and you come to an encyclopedia because you want to know roughly where Chicken fits into the general scheme of things. If you contribute, do please also say hello on my user talk page: http://en.wikipedia.org/wiki/User_talk:Tony_Sidaway ___ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users