Monday, December 03, 2012

Making schematics look good with "gaf export"

<CareBear\> peterbrett : hey. gaf export is f-ing awesome!

People who've been testing the gEDA "master" branch over the last few hours will have got a sneak preview of a cool new tool that will be arriving in gEDA/gaf 1.9.0. The new gaf export command-line utility lets you quickly and easily export your schematics and symbols to a variety of image formats.

I've been wanting to introduce a tool like this for a while, but it's only become possible thanks to finally finishing a couple of big features that have been cooking in my personal branches for a couple of years: a new Cairo-based rendering library for gEDA designed to be used for both rendering in gschem and for printing/exporting graphics, called "libgedacairo"; and a new gEDA configuration subsystem, which I'll write about in more detail another time.

To get started, suppose I want to create a PDF from a schematic called grey_counter_1.sch. It's very straightforward!

gaf export -o grey_counter_1.pdf grey_counter_1.sch

From the output filename that I passed to the "-o" option, gaf export will detect that I want a PDF. It'll detect the size of the drawing, centre it in the default paper (choosing some suitable margins) and generate a PDF file.

Batch generation of PostScript files

Many people previously used gschem along with the (relatively obscure) print.scm script for batch generation of PostScript files. Usually the command looked something like:

gschem -o grey_counter_1.ps -s /usr/share/gEDA/scheme/print.scm grey_counter_1.sch

Don't do this any more. It is slow (because it needs to load all of gschem's configuration), requires an graphical desktop to be running (because gschem can't start without trying to display its windows) and doesn't provide any way to directly customise formatting options without fiddling with Scheme scripts. Also, gaf export generates much nicer PDF output than PS, especially if you want to do anything with the output file other than printing. You could directly replaced the gschem command above with something like:

gaf export -o grey_counter_1.pdf grey_counter_1.sch

A Makefile rule for creating PDF files from schematic files might look like:

%.pdf: %.sch
	gaf export -o $@ -- $<

Of course, one advantage of the new tool is that it can do multi-page output. So rather than generating a whole bunch of separate PDF or PostScript files and stitching them together, you could directly generate a single PDF file with the whole of your design in it:

gaf export -o schematics.pdf grey_counter_1.sch filter_1.sch

Tweaking the output

gaf export also lets you tweak the output for different applications. Suppose I want to produce the PNG file displayed in this blog post. First, I don't care about paper sizes; I want the output file to be sized according to how large the drawing is. To do this, I can use -s auto. I can also set the margin on the output with -m 5px. I also want to print in colour (-c). So the overall command is:

gaf export -c -s auto -m 5px -o gaf_export__40160-1.png 40160-1.sym

It can also be useful to set the paper size (for example, to get suitable margins for larger paper sizes). By default, gaf export uses whatever GTK thinks the default paper size is on your system. For most people, this will be ISO A4. In addition to providing measurements directly via the -s option, the -p option lets you specify a PWG 5101.1-2002 paper name. For example, to use US "D" size paper:

gaf export -p na_d -o grey_counter_1.pdf grey_counter_1.sch

Changing default settings

The default settings for gaf export can be modified using the new gaf config command. For example, to set the default paper size for all your projects to US "Letter":

gaf config --user export paper na_letter

Or to make sure that all printing for a particular project is in colour:

gaf config -p /path/to/project/directory/ export monochrome false

Conclusion

gaf export is a fast, easy-to-use way of generating graphics files from your gEDA/gaf schematics and symbols. Along with several other new features, it will be available in the upcoming unstable gEDA/gaf 1.9.0 release.

Monday, May 14, 2012

Remote Sensing journals and open access

The Remote Sensing Applications Research Group at Surrey Space Centre is in the first stages of thinking about the new Research Excellence Framework (REF) system that will be used to assess the quality of our research.

We've been told by the University that we each need to demonstrate four "research outcomes" for REF. Initially, we've been given the advice that an appropriate "outcome" would be a journal paper published in one of the "top five journals in our field", as determined by various arbitrary and generally misleading journal metrics. Unfortunately, at a recent meeting to discuss this, we realised that there were a few problems with this; for example, the list of "remote sensing" journals as categorised by the ISI Web of Knowledge Journal Citation Reports included quite a few journals that would have been completely inappropriate for our work, while some highly relevant and high-profile journals such as IEEE J-STARS were a long way down the list due to being newer and not yet having had time to accrue high-scoring metrics.

However, I noted and was asked to further investigate another potential problem with our list of target journals: the problem of up-and-coming open access mandates from our UK funding bodies.

The 2001 Budapest Open Access Initiative defined open access as:

Free availability on the public internet, permitting any users to read, download, copy, distribute, print, search, or link to the full texts of... articles, crawl them for indexing, pass them as data to software, or use them for any other lawful purpose, without financial, legal, or technical barriers other than those inseparable from gaining access to the internet itself.

The policy that the UK Research Councils (RCUK) are proposing to adopt in the near future would make it mandatory to publish results from research that is wholly or partially funded by the research councils in journals that meet RCUK standards for open access. This is a significant departure from the previous position, where open access publishing even of research council-funded results has been effectively optional. The key points from the draft policy seem to be:

  • A user must be able to access, read and re-use papers free of charge under an extremely permissive licence. RCUK explicitly identify the Creative Commons CC-BY licence as a model.
  • Open access to the paper may be provided directly by the publisher via the journal's website at the time of publication ("Gold OA"; publishers may charge the authors for this), or the author can archive the final version of the paper as accepted for publication in an online repository other than one run by the publisher ("Green OA"). Surrey Research Insight is an example of such a repository. Journals are allowed to impose an embargo of at most 6 months.
  • RCUK grant funding can be used to pay publishers for Gold OA publication, and researchers are recommended to request funding for this in grant applications.

The question, therefore, is: to what extent do "remote sensing" journals comply with this policy? To answer this, I examined the publication policies of all English-language journals in this category with respect to self-archiving of the accepted version of a paper (Green OA), the "normal" published paper, and (if applicable) paid-for open access publication (Gold OA), using the SHERPA RoMEO database, Ross Mounce's publisher licence spreadsheet, and publishers' websites. My results are shown in Table 1.

Table 1. Remote sensing journal compliance with proposed RCUK open access rules, sorted in descending order of impact factor. "R" indicates restrictions on "open access" options that prevent full compliance. Minimum publication fees are shown in brackets.
NamePublisherRegularGreen OAGold OA
Remote Sens. Environ.ElsevierNoRR ($3000)
IEEE Trans. Geosci. Remote Sens.IEEENoRR ($3000)
ISPRS J. Photogramm. Remote Sens.ElsevierNoRR ($3000)
J. GeodesySpringerNoRYes ($3000)
Int. J. Appl. Earth Obs. Geoinf.ElsevierNoRR ($3000)
GPS Solut.SpringerNoRYes ($3000)
Int. J. Digit. EarthTaylor & FrancisNoRR ($3250)
IEEE Trans. Geosci. Remote Lett.IEEENoRR ($3000)
Int. J. Remote Sens.Taylor & FrancisNoRR ($3250)
IEEE J. STARSIEEENoRR ($3000)
GISci. Remote Sens.BellwetherNoNoNo
J. Appl. Remote Sens.SPIENoRUnclear ($1500)
J. Spat. Sci.Taylor & FrancisNoRNo
Can. J. Remote Sens.Can. Aeronautics and Space Inst.NoNoNo
Radio Sci.AGUR ($1000)RR ($3500)
Photogramm. Eng. Remote Sens.ASPRSNoUnclearNo
Photogramm. Rec.Wiley-BlackwellNoRR ($3000)
Mar. Geod.Taylor & FrancisNoRNo
Surv. Rev.ManeyNoRR ($2000)
Eur. J. Remote Sens.Assoc. Ital. TelerilvamentoYesN/AN/A

The most common restrictions encountered on Gold OA content were prohibition of commercial use (e.g. via explicit Creative Commons CC-BY-NC licensing), prohibition of redistribution, and field-of-use restrictions such as prohibition of text-mining. In addition to these restrictions, in several cases self-archiving was only permitted with an embargo period of more than 6 months. One somewhat bizarrely convoluted rule for Elsevier journals can be boiled down to: "You may archive the accepted version of your paper in your funding body's repository, but only if you don't have to archive it in your funding body's repository."

At this stage, Springer's recent change to CC-BY licensing of papers in their "Open Choice" system is particularly notable. It's also clear our current target journals (IEEE Trans. Geosci. Remote Sens. and IEEE J-STARS) still have some way to go before they will be BOAI-compliant or compliant with the proposed RCUK publication requirements. In my opinion, over the next few years a good outcome would be for publishers like IEEE and Elsevier to standardise on CC-BY publication for Gold OA publications.

In the short term, I will be recommending to my group that we should consider submitting to open access megajournals such as PLoS ONE, many of which have considerably higher journal metrics than any of the dedicated remote sensing journals. Adding PLoS ONE to the Space Centre's list of preferred journals should not be particularly controversial, as it is already listed as a preferred journal for other research centres in the faculty.

In conclusion, I have demonstrated that the open access publishing options available in the field of remote sensing are limited, and that this may become a problem if stricter rules, similar to those set out by the Budapest Open Access initiative, are laid down by the UK Research Councils. Either journal publishers will have to change their policies, or research groups in this field will need to consider different publishing strategies.

This post is made available under a Creative Commons Attribution (CC-BY) licence.

Friday, May 04, 2012

Planning the Guildford Cycle Network

Since soon after arriving at the University of Surrey to begin my PhD studentship and discovering the terrible state of cycling infrastructure in Guildford, I started attending Guildford Cycle Forum meetings to try and discuss what could actually be done about it. For most of that time, the meetings have had a rather predictable format: a chorus of Forum members pointing out problems experienced by cyclists and opportunities to fix them, countered by County and Borough Council officials explaining either that no budget exists for cycling improvements, or that the changes requested weren't in their department and they couldn't address them.

Recently, however, some money has finally become available via the government's Local Sustainable Transport Fund (LSTF), and Guildford is hoping to receive approx. £900,000 of it, a large chunk of which is intended to fund cycling improvements.

A major component of Guildford's bid is the establishment of a network of cycle routes within Guildford. On Thursday 3rd May, Alan Fordham, the "Sustainability Programme Delivery Officer", hosted a Guildford Cycle Forum meeting at the Guildford Borough Council offices to present and discuss the routes that are currently planned for the network.

A total of fourteen local cycle routes are planned to be defined, mostly radial routes fanning out to the north from the town centre, which actually lies in the southern part of the town. Unfortunately, the route maps that Alan handed round at the meeting aren't available online anywhere yet; I asked him to circulate some digital copies by e-mail, but in case he doesn't get time to do so I will try to copy them onto Google Maps or something.

In following blog posts, I plan to discuss the routes and the weaknesses that I see in them based on my experiences cycling to and from Guildford every day. However, in this post, I want to discuss some more general points about the plans.

The most important point which I haven't seen addressed is what the overall objective of the project is, and how it will be assessed. In my opinion, the logical objective is modal shift, where journeys currently made by car are transferred to other forms of transport, and both the design of the network and its performance should be judged by how well it achieves that. I think this is supported by the purpose of the LSTF, which is to help promote the use of and migration to sustainable transport.

Tying into this point, one of the things that really isn't clear to me is what type of cyclist the routes are intended for.

  • Are they intended to be used by regular cycle commuters? Many of this class of cyclists will be aiming to cycle quite quickly and travel at all times of year in all weather conditions. Quite often they will be travelling at rush hour, and given rush-hour congestion and aggressive driving, would likely welcome the addition of good new cycle routes. These cyclists desire routes that have good sight lines, are no more obstructed than roads, and facilitate bidirectional flow well. Unfortunately, these kind of requirements can be very difficult to accommodate well without new, purpose-built segregated cycle facilities or the provision of mandatory on-road cycle lanes. I am one of these users.
  • Are they intended as an 'easy option' to attract occasional cycle commuters? The provision of signposted routes might be the key to persuading people to take up cycling to work, but if the routes are too much slower than driving, or have significant sections that put them in conflict with rush hour traffic, they might be put off. To me, this is a core target group, as moving them to cycling will often directly replace a single-occupant car journey, and I suspect that the problem may not be getting them cycling as keeping them cycling.
  • What about parents taking their children to and from school? When I was in Cambridge, I used to see a couple who would cycle to work at the university on their tandem, taking their children with them in a trailer and dropping them off at primary school on the way. For this kind of user, the routes really need to be accessible either when towing a trailer or when using one of the Dutch-style family carrier bikes with a bay in the front (these are also really good for shopping, or so I hear). For these cyclists, who are often heavily laden, it is important to provide facilities that are wide enough to accommodate them and have few sharp corners. Even a single chicane like this one can make a route impassible.
  • Are the routes intended to be used for school travel by children old enough to ride their own bikes, but not experienced or confident enough to fall into one of the first two categories? For these users, good segregation of cycle routes from traffic is important, because they will commonly want to ride with their friends and might be easily distracted from paying attention to other vehicles. Another factor is that, unfortunately, many of these users will be using equipment that is incomplete or in poor condition (e.g. bad brakes, or no lights), and once again, good segregation may be key in keeping them out of danger.
  • Or are the routes intended for casual cyclists and cycle tourists? These users, who will usually be travelling with a flexible itinerary, in favourable weather conditions, and at times of day when traffic is relatively light, can be accommodated much more easily than any of the other types of user described above.

In following blog posts, I will try to consider the proposed routes with reference to how suitable they are for each of above types of user. Unfortunately, one of my biggest worries about the network as a whole as it is currently envisaged is that it accommodates the last of those classes of user really well, but that many of the routes are fatally flawed for any of the other groups to depend on. Because of that, I worry that the objective of getting many people living in Guildford to change to cycling might be compromised.

Another problem is that there is very little money actually allocated under the plan to major improvement works (such as altering junctions to make them safer for cyclists, or changing road layouts to add cycle lanes of appropriate width), and that the main Surrey County Council highway planning department doesn't seem to be involved in the process. As far as I can tell, this seems limit the project to mostly an exercise in putting up signposts to direct cyclists onto the least inadequate of the existing routes (and even then, one of the Cycle Forum members raised the "environmental concern" that "ugly" signs were "unnecessary"). Fortunately, however, there are a few improvements being made to some of the most obviously hopeless spots.

Overall, I think that just the fact that this project is taking place is a major step forward for cycling in Guildford, finally making a move onto the long road towards making Guildford a town that's genuinely accessible by bicycle.

In my next post, I will investigate Route 4: Wooden Bridge to Jacobs Well, and how well it holds up during rush hour.

Saturday, March 10, 2012

Leek and potato soup

It's been a while since I lasted posted a recipe. Here's a recipe for some delicious leek and potato soup that I first tried out last Christmas. Serves 3-4.

  • 1 medium onion
  • 2 cloves garlic
  • 2 large leeks
  • 350 g potatoes
  • 250 ml white wine
  • 150 ml double cream
  • 1 tbsp olive oil
  • 2 tsp vegetable bouillon powder

Peel and dice the potatoes.

Finely chop the onion and leeks and, using a large heavy-based saucepan, fry gently in the olive oil over a medium heat for 2-3 minutes. Crush and add the garlic, and fry for a further 1 minute. Meanwhile, boil a kettle.

Add the potatoes, wine and bouillon powder to the pan, with enough boiling water to just cover the vegetables. Add salt and pepper to taste.

Turn the heat down to a simmer, and cook for 30-40 mins until the potatoes are nice and soft. Blend or mash the soup, and finally stir in the double cream just before serving.

Tuesday, January 31, 2012

Paper for EUSAR 2012

I'll be presenting a paper in an invited session on urban remote sensing at this year's European Conference on Synthetic Aperture Radar (EUSAR 2012). The preprint is now available on my website.

  • P.T.B. Brett and R. Guida. Geometry-Based SAR Curvilinear Feature Selection for Damage Detection. In 9th European Conference on Synthetic Aperture Radar - Invited Papers (EUSAR 2012 - Invited Papers), 23-26 April 2011. [Preprint]

In other news, I will be joining the boycott of Elsevier and their journals, and I encourage other researchers to do the same. Their behaviour is actively damaging to science.

Wednesday, December 28, 2011

Coming up to gEDA 1.7.2

Later this week, gEDA/gaf 1.7.2 will be released! Hopefully, this will be the final unstable release before gEDA/gaf 1.8.0, and it will contain a few neat new things that we've been working on over the last six months.

  • As I've discussed previously, this release will incorporate all of the basic Scheme API functionality, to make it easier to write extensions for gschem in pure Scheme. I've had quite a few e-mails and feature requests from people who have been doing interesting things with the new API, and I'm looking forward to hearing about more tools for enhancing gschem! All of the new functions are documented in the gEDA Scheme Reference Manual.
  • In terms of documentation, I've completely re-written the gschem User Guide, more fully describing many features in gschem that were previously poorly documented, and hopefully making it easier to find the information you need. Gareth Edwards has done a fantastic job of adding man pages to gEDA, and now all of the programs we install have a properly-written man page.
  • The first parts of my rework of keymapping will also be included. Now key names will be properly internationalised when they're displayed, and having Caps Lock enabled will no longer mess up your keybindings. You can also now bind key combinations that use the Mod, Super or Hyper modifier keys.
  • You can now read gEDA documentation on Windows! (About time, really).

What's next once 1.7.2 has been released? Well, the most important thing is going to be to get a new stable release out. Many distributions are keen to move to Guile 2.0.x, and the current stable version of gEDA (1.6.2) doesn't support it. My current hope is to go into a string freeze for gEDA 1.8.0 very soon after gEDA 1.7.2 is released, and aim to get all the translations updated in time for a stable release at the end of January 2012.

There are many exciting plans for the 1.9.x branch of gEDA, but I'll leave them for another time...

Thursday, June 30, 2011

Scheme API merge, and keybinding in gschem

Earlier this week I merged the gEDA Scheme API that I've been working on since late 2009 into the main gEDA unstable branch. It's been a pretty great chunk of work, and I'm glad to have been able to get it into a state where it's generally useful. It's been pretty fun working out how to answer users' feature requests on gEDA-user with a short Scheme function, too! Hopefully people will take this new feature and do cool things with it.

One of the main obstacles to doing cool things with the new Scheme API is that it's difficult to modify key bindings on the fly — gschem doesn't have any equivalent to Emacs' global-set-key, for example. That makes it hard for e.g. an rc file or Scheme plugin loaded after system-gschemrc to add new keybindings or modify existing ones. There's also only a single keymap, so there's no possibility for user-modifiable state-specific keymaps (e.g. for binding keys that the user presses while placing a symbol).

While on the subject of keybindings, the way gschem currently displays keybindings in the menu bar is a little bit rubbish — for example, it would be good to display "]" instead of "bracketright", and "o S" instead of "oShift S". It's also a shame that we don't support a wider range of modifier keys, including "super" ("⊞" on most keyboards).

I'm planning to fix all these issues by adding a comprehensive set of Scheme functions for working with keys, key sequences and key bindings to gschem. Keymaps will probably become a hashtable-based record type, and there will be functions for creating a key sequence from a string and vice versa. There will also be a function for obtaining a "pretty" string describing a key, suitable for displaying in a menu or in the status line.

Saturday, June 25, 2011

The gEDA Scheme API manual is here

I'm currently working to get my guile-scheme-api branch ready to merge into the main unstable gEDA branch (master). One of the main jobs that needed to get done before that's possible was to write a reference manual for all of the Scheme functions and variables that the new Scheme API provides, and I've now done that!

If you're interested in writing extensions for gEDA, please take a look at the draft gEDA Scheme Reference Manual and let me know what you think. I'm keen to receive any feedback you might have, whether about the manual or about the API itself.

I'm hoping to merge my work so far in this branch into unstable within the next week. At the same time, I'm aiming to add the following missing functionality as soon as possible:

  • Object transformations (translation, rotation and mirroring)
  • Picture object creation and manipulation
  • Path object creation and manipulation (quite tricky, unfortunately)
  • File saving and loading
  • Picture and component embedding/unembedding

These are all things that I'm sure extension authors would be quite interested in having available to them! Hopefully we'll see all sorts of interesting new capabilities for gEDA users coming out soon.

Thursday, June 16, 2011

gEDA and Guile — opportunities to get involved

This is the eighth and last in a series of posts on extensibility in gEDA using Guile Scheme.

  1. Finding Scheme API code in gEDA
  2. Compiling against multiple Guile versions
  3. Safe handling of non-local exits
  4. Dealing with deprecated libguile functions
  5. Checking arguments to Scheme functions in C
  6. How and when to use Scheme errors
  7. Reducing boilerplate with "snarfing macros"
  8. Opportunities to get involved

In this post, I'll summarise the series. In addition, I'll recap on the opportunities to get involved in gEDA development offered by the problems I've identified with the current gEDA codebase.

In my first and second posts, I described whereabouts in the gEDA codebase to find code which uses Guile, and also how to set up a build environment to easily compile gEDA against either Guile 1.8 or Guile 2.0. Being able to test with the latest stable release of Guile is quite important, and should definitely be considered by all gEDA developers!

In my third post, I dealt with probably the most important issue: dealing with non-local execution due to Scheme exceptions and continuations. There are a lot of places in gEDA where it's assumed that a call to a libguile or Scheme function will return normally, and that's not a safe assumption. Failing to protect against that (e.g. by using the "dynamic wind" mechanism) can easily result in resources being leaked.

The following post explained how to get notified when gEDA uses deprecated Guile APIs. It also gave an example of an instance where using deprecated API long after its deprecation has lead to actual bugs — the SCM_STRING_CHARS() and SCM_SYMBOL_CHARS() macros.

I went on to talk about the use of Scheme errors. I described the use of the SCM_ASSERT() macro to check function arguments, and also how to use Scheme errors more generally. The main points to remember here were that libguile has some really useful undocumented helper functions for raising Scheme errors from C code (see libguile/error.h), and that just because SCM_ASSERT() has "assert" in its name doesn't mean that you don't have to be careful about resource management if the test fails.

Finally, I talked about the guile-snarf tool that's used by my guile-scheme-api branch to generate boilerplate code for defining Scheme functions and variables from gEDA's C code.

There are several opportunities to get involved in making gEDA better. All these jobs are good for people who aren't that familiar with gEDA development, but who want to get to learn the codebase and about the development process, because they can mostly be done just on a function-by-function basis.

  • You can help change places where SCM_STRING_CHARS() is still used, to use scm_to_utf8_string() instead. I've already had some patches from Ivan Stankovic to deal with some of these!
  • You can look at the places where gEDA calls into libguile or calls Scheme functions to make sure that any potential errors are handled properly.
  • You can double-check that all gEDA functions that take SCM arguments validate them properly using SCM_ASSERT().
  • Or you can help make sure that gEDA Scheme functions raise Scheme errors properly when things go wrong.

If you're interested in submitting patches addressing any of these, or have any questions, please get in touch.

As previously mentioned, my focus for gEDA development in the near future is going to be on getting my guile-scheme-api branch merged, and I encourage everybody to try it out and let me know what you think! For information on my various branches and how to get hold of them, please see my gEDA development page.

Wednesday, June 15, 2011

gEDA and Guile — reducing boilerplate with "snarfing macros"

This is the seventh in a series of blog posts on extensibility in gEDA using Guile Scheme.

  1. Finding Scheme API code in gEDA
  2. Compiling against multiple Guile versions
  3. Safe handling of non-local exits
  4. Dealing with deprecated libguile functions
  5. Checking arguments to Scheme functions in C
  6. How and when to use Scheme errors
  7. Reducing boilerplate with "snarfing macros"
  8. Opportunities to get involved

In this post, I will explain how you can use the guile-snarf tool to reduce the boilerplate needed to define Scheme functions and variables from C.

At the time of writing, this post isn't really relevant to the main gEDA unstable development branch, since it doesn't currently use "snarfing". It might be an interesting read if you're interested in hacking on my guile-scheme-api branch.

Why is "snarfing" needed?

One of the problems with using libguile to define Scheme functions from C is there's a certain amount of boilerplate setup code. For example, if I wish to define a function called "myfunc" in C to be usable from Scheme, I need to do something like:

static SCM
my_func (SCM arg)
{
  SCM_ASSERT (scm_is_string (arg), arg, SCM_ARG1, "my-func");

  /* ... do something useful ... */
}

/* Called during application initialisation */
void
my_init ()
{
  scm_c_define_gsubr ("my-func", 1, 0, 0, (SCM (*)()) my_func);
}

There are a few problems with this.

  • If the number of arguments to the function changes, an update needs to be made in two different places.
  • If the string name of the function changes ("myfunc" in this case), an update needs to be made in two places, and also to every other place the name is used (e.g. SCM_ASSERT() for arguments and any other place a Scheme error is raised).
  • If an extra function is added...

You get the idea.

Similarly, if there is a permanent Scheme value that's needed in multiple functions (such as a symbol) it's necessary to separately define the static variable and add a line to the initialisation function.

Finally, if the libguile API for defining a function or variable changes, it's necessary to individually update the initialisation code for every single one.

The guile-snarf tool

Guile comes with a tool called guile-snarf, which is run against a C source file to generate an additional C source file for inclusion, usually given a .x extension.

The tool recognises some special macros in the C source, which expand normally when compiled, but which are used by the tool to generate Scheme initialisation boilerplate. The example above would become:

SCM_DEFINE (my_func,   /* Function name in C */
            "my-func", /* Function name in Scheme */
            1, 0,      /* No. of required/optional args */
            0,         /* Whether accepts "rest" arg */
            (SCM arg), /* C argument list */
            "Do something exciting.") /* Docstring */
{
  SCM_ASSERT (scm_is_string (arg), arg, SCM_ARG1, s_my_func);

  /* ... do something useful ... */
}

/* Called during application initialisation */
void
my_init ()
{
  #include "mycfile.x";
}

This may seem like a small gain for this trivial example, but for files which define a large number of Scheme procedures there's a definite benefit! There are a few things to note:

  • Functions defined using SCM_DEFINE() are always static. This shouldn't normally be a problem, since they will usually be intended to be called from Scheme, not from other C functions.
  • For each function foo, SCM_DEFINE() also defines a static string called s_foo. This can be pretty handy, especially when needing to pass the Scheme name of the function to SCM_ASSERT() macros. (Its use is discouraged by the official documentation, but libguile itself makes use of it, so hey — it can't be that much of a problem!)

Although SCM_DEFINE is the main reason to use guile-snarf, there are several other really useful macros, such as SCM_SYMBOL("foo"), which creates & defines a variable containing the symbol "foo". In my guile-scheme-api branch, you will fairly commonly see a block at the top of a C source file looking like:

SCM_SYMBOL (lower_left_sym , "lower-left");
SCM_SYMBOL (middle_left_sym , "middle-left");
SCM_SYMBOL (upper_left_sym , "upper-left");
SCM_SYMBOL (lower_center_sym , "lower-center");
SCM_SYMBOL (middle_center_sym , "middle-center");
SCM_SYMBOL (upper_center_sym , "upper-center");
SCM_SYMBOL (lower_right_sym , "lower-right");
SCM_SYMBOL (middle_right_sym , "middle-right");
SCM_SYMBOL (upper_right_sym , "upper-right");

This then allows functions in the file to use the symbols to construct Scheme expressions to be evaluated without needing to recreate the symbols (e.g. using scm_from_utf8_symbol()) every time the function is run.

Conclusion

Currently, when wishing to alter the prototype a Scheme function provided by a gEDA program, you need to make changes in at least three places:

  1. The function definition itself.
  2. The function prototype in a header file.
  3. The function metadata exported to Scheme, usually in a file called g_register.c.

Using the SCM_DEFINE() "snarfing" macro and the guile-snarf tool would allow two of those places to be eliminated, and that's why my guile-scheme-api branch uses them.

The next and final post in this series will summarise the things I've written about, and give a list of easy introductory gEDA development tasks based on some of the issues I've raised.