
As I mentioned in January, I was awarded a PhD studentship at Surrey Space Centre. I graduated from Cambridge last Friday, with I Class honours in my BA and a Distinction in my MEng, moved down to south-west Woking at the weekend, and started at SSC today!
I'm having to fight a bit to get a Linux workstation -- other groups in the same building (and serviced by the same IT staff!) use Fedora on their desktops, but SSC has historically been an all-Windows environment. In a corporate setting, I might put up with Windows -- there, at least, there is often a reasonably well-staffed IT services department to take care of the innumerable things that go wrong -- but in my experience, PhD students don't get quite that level of support. If I'm going to be solving my own problems, I want to do it with more powerful tools. (Also, Emacs on Windows isn't nearly as much fun. How can I possibly survive without a properly-functioning compilation-mode?)
Nevertheless, I think I'm eventually going to win the battle. In the meantime, it looks like I'll have to make do with Cygwin.
As far as the research is concerned, I've barely start to dip my big toe into the scalding bathtub of things I don't know, and it feels like I've got a long, long way to go before I get to the things no-one else knows either!
Another chorizo recipe that I made to use up what was left over from the previous one. Note that I use Spanish chorizo, not Mexican (as most commonly found in the USA).
Ingredients (serves 3-4):
In a wide-based saucepan, heat a tablespoon of olive oil, and fry the onion and chorizo for 2-3 minutes (or until the onion is translucent). Add the mushrooms and garlic, and continue to fry until the mushrooms begin to darken and shrink. Add the tomatoes, and stir in the dried tarragon, bay leaves, black pepper, and about a tablespoon of balsamic vinegar. Cover and simmer gently for 20-30 minutes.
Serve with pasta and fresh green salad.
Here's a simple but delicious recipe I adapted from a dish served at Girton's cafeteria sometime in early 2009.
Ingredients (serves 2):
Pre-heat the oven to 180°C (fanless oven 200°C). Sprinkle both sides of the chops with salt, and place in a small roasting tin. Pile garlic, onion and chorizo on and around the meat. Add pepper on top. Cover the roasting tin with tin foil and bake in the oven until the meat is cooked (usually between 45 mins and one hour).
Serve with boiled potatoes and fresh cabbage.
I've been accepted for a PhD studentship at Surrey Space Centre, working on applications of satellite-based Synthetic Aperture Radar (SAR). Even better, I've been awarded a Doctoral Training Grant by the EPSRC, so as long as I pass my MEng I'm going to be going exactly where I've wanted to go for the last couple of years, doing (more or less) exactly what I want to do!
Just over a week ago, I posted a series of [RFC] posts to the gEDA-user mailing list suggesting six reasonably non-trivial changes to libgeda and gschem. Although the discussions they started off weren't quite as productive as I was hoping, they did attract quite a bit of interest.
I haven't been afraid to put my money where my mouth is. Since then, I've implemented two of the changes I suggested: a modification of the way gEDA apps create logfiles, and support for copying and pasting bits of schematics between gschem windows. I thought I'd post here to explain the amount of careful design work that goes into even relatively minor changes to the gEDA suite.
Historically, gschem (and the other gEDA apps) have created logfiles in the current working directory when they were launched. This behaviour quickly resulted in a user's home directory becoming littered with the files, gschem.log files especially.
My initial suggestion was to just not create log files by default, and require users to specifically enable them. However, it was quickly pointed out that since one of the most common reasons for gschem failing to start was that a new user had made a mistake in their configuration file, and that it would be best to carry on with generating logfiles as the default behaviour.
Instead, it was suggested that the logfiles should be put in a centralised, out-of-the-way location, and ~/.gEDA/logs/ was suggested, with the caveat that it would be necessary to make sure that multiple copies of gschem accessing the directory would have to be supported safely, even on different machines, but also that a user could quickly easily find the most recent log file -- so just adding a random suffix with mktemp wouldn't work either!
Having worked out a way of doing this (a secure algorithm for generating sequentially numbered, dated log files), I then realised that on some operating systems, such as Microsoft Windows, $HOME might not even be defined, and that there might be platform-specific differences in the standardised place to keep configuration data. Since the gEDA applications had no existing way of handling these variations, I ended up abstracting out the methods for locating the system and user data and configuration files, and updating all of the gEDA apps to use them.
All in all, changing the location where log files are stored used up at least eight hours of development time.
For a long time, gschem has supported copying and pasting schematic data between pages and windows in the same gschem process, but it was never made clear to users that this mechanism didn't use the X clipboard, and thus sometimes copying and pasting didn't work when it would have made sense for it to.
X Window System selections are complicated. There are two selections normally used by X applications: the PRIMARY selection and the CLIPBOARD selection. Traditionally, the PRIMARY selection is contains the most recent piece of text selected by the user with the mouse, and can be pasted by clicking the middle mouse butten, while the CLIPBOARD selection is accessed via "copy" and "paste" actions explicitly invoked by the user. In order to match up with other applications (and because nothing like the PRIMARY selection is available on Microsoft Windows or OS X), we decided to use the CLIPBOARD.
For the same portability reasons (and also because the raw X API is horrendously complicated), we decided to use the GTK Clipboard API to manage the clipboard.
A neat feature of clipboards (and X selections in particular) is that it's possible for the source application to provide the data in different forms, depending on what the "pasting" application wants. We needed a format for transferring between gschem instances, so we decided to use the gEDA schematic format (application/x-geda-schematic). Fortunately, as part of my rewrite of the symbol library back in mid 2007, I'd made libgeda able to "load" and "save" schematics from memory buffers, so I simply hooked the clipboard code into that and things started working!
I then, of course, had to work through the boilerplate required to update the GUI to support it. This took as long as implementing the actual feature.
I've also been working on some other features, using some code that I've had floating around for a long time. But more of that another time!
I tried out two recipes yesterday, with lots of success (well, I thought so, anyway).
First was nice and simple recipe for lemon drizzle cake from the BBC Good Food website -- I used it as a fallback plan when I failed to obtain a copy of my mother's legendary and delicious recipe.
I made it in a 20 cm spring-form tin instead of a loaf tin as the recipe suggests (I don't have a loaf tin at the moment). This meant it only took around 40 minutes rather than the 45 to 50 suggested, due to the cake being somewhat wider and flatter.
The cake was delicious, but a little dense; next time I will try adding an extra teaspoon of baking powder to try and lighten it slightly.
The second was a Thai-style dish called khao pad gai from a WikiBooks Cookbook recipe. Due to the limited contents of my food cupboard and my unwillingness to buy lots of unusual and seldom-to-be-used foodstuffs, my version of the ingredients (to feed two) looked more like:
We didn't bother with the garnish, the nam pla or the Thai chili sauce, but nevertheless the taste came out okay (we were quite pleasantly surprised by how good it was after how awful it looked just after the egg was added). Note that although the recipe specifies a wok, we cooked it quite successfully in a large, flat-bottomed non-stick saucepan.
I've been doing a lot of work that's required me to keep an eye on word counts recently, so I've needed a decent word count function in Emacs. The easiest way to implement this was to use the wc command from CNU coreutils.
(defun word-count nil "Count words in buffer" (interactive)
(let ((start (if mark-active (point) (point-min)))
(end (if mark-active (mark) (point-max))))
(shell-command-on-region start end "wc -w")))
If the the mark is active, it counts the number of words marked, otherwise counts the entire buffer. I have this bound to C-c C-w.
I also extended tab completion with dabbrev-expand to all file buffers, so I can use it in MATLAB, Bash, Python, etc. This was inspired by doing lots of MATLAB programming recently at my newly started summer job at Cambridge Silicon Radio.
(defun indent-or-complete ()
"Complete if point is at end of a word, otherwise indent line."
(interactive)
(if (looking-at "\\>")
(dabbrev-expand nil)
(indent-for-tab-command)))
(add-hook 'find-file-hook
(function (lambda ()
(local-set-key (kbd "<tab>") 'indent-or-complete))))
Having been horribly ill for what feels like most of December, Christmas is now here! I'm spending Christmas with my parents and all of my siblings, and it seems like I've been running around like a mad things for the last few days getting everything clean, tidy and ready for Christmas. On Christmas Eve my mother and I were at the butchers' shop at half past six in the morning to get the turkey and other bits we needed! This was most certainly a better option than waiting in the hour-long queue that had formed by the time I returned to the town centre later in the morning to do some other shopping.
Although being miserably ill put a big damper on my plans to do vast amounts of gEDA development during December, I've nevertheless managed to get some useful stuff done, further based on the libgeda error reporting issues discussed in my last couple of posts.
Firstly, I improved the way in which errors in Scheme files were reported. Messages reporting errors in gEDA rc files often reported the error as occurring in the wrong file, and claimed every error was a parenthesis mismatch (often when they were nothing of the sort). The error messages were also sent directly to the console rather than to the gEDA logging mechanism. Using deep dark Guile debugging magic, any errors encountered while reading in rc files now logs a backtrace, and tries to report the actual file and line on which the error occurred.
Secondly, and more importantly, I added internationalisation support to libgeda using gettext. As there are many international users of gEDA, and many important messages generated by libgeda, I feel that this is a very important development.
I'm hoping that we can use the web translation tools offered by Launchpad to make translating gEDA easier for users, and thus increase the quality and number of translations.
Peter Clifton and I have also been working hard on getting gEDA ready for a new release, squishing as many serious bugs as possible. Peter Clifton has particularly excelled himself, creating stunning icons for all the main file types used by gEDA.
In the next development cycle, I hope to substantially increase the flexibility of the component library. In particular, I hope to make it possible to have truly independent library setups, so that it is possible to have schematics from different projects with different libraries open in the same gschem session without any conflicts. I also hope to generalise the library infrastructure so that the same basic code can be used for the component library, hierarchy source library and any other library of reusable resources which might need to be added in the future.
As a first step along the route to the Ultimate Resource Library, however, the way that the Scheme extension API works needs to be rationalised, and once Christmas starts to wind down, I hope to deal with this. It will involve fluids.
Update: My blood test results have arrived, and it turns out that I have glandular fever. Absolutely fantastic.
Further to my previous blog post on error-reporting in libgeda, I've made some pretty good progress on implementing the ideas that I described. In particular:
These changes are not yet in the unstable branch, but barring someone objecting to my changes I'll push them upstream tomorrow sometime.
The next (probably thankless) task is to work through libgeda converting all calls to directly output debugging/error-reporting information to the console to use the GLib logging functions instead, and to make log messages be sent at appropriate levels rather than all at the "message" level (this will allow filtering of log messages in the gschem log window, for instance).
I'm still of two minds about the best way to do this. Currently, libgeda defines a macro s_log_message() which is equivalent to GLib's g_message(). For adding logging at multiple levels, the two options are:
I'm currently leaning towards the latter, but haven't as yet made up my mind about exactly which will be the best way to go.
Apparently some people do read my blog: Peter Clifton and I met up for a drink at Borders in town this evening, and he recommended that I write more often. So here's this evening's contribution, on a slight refactor of libgeda error reporting.
It's been a while since I last blogged about gEDA development, and since then I've had the good fortune to be able to travel to Cambridge, MA and meet several of the other developers based around there. In the last couple of days I've started ramping up my involvement in preparation for having some time for serious development over the Christmas vacation.
So, to begin: in general, libgeda kills the process without warning far too often. This is a bad thing for a library to do; in particular, it's very bad to do it just because someone passed some bad data in. The libgeda doesn't make any attempt to hide how the data structures are organised, and thus we have to assume that user code will make use of this knowledge to try and hack them directly.
My pondering of this problem over the last couple of days has lead me to think up four basic rules to consider when working out how to handle errors occuring in libgeda code:
Of course, some of these need a little explanation as to their interpretation and why they make sense.
Firstly, "If possible, succeed." This seems obvious, but actually has some subtlety. What I mean here is that if there's a sensible, clean way of carrying on despite a problem, you should do so. This only really applies to user-facing code, as code which can't be called from outside libgeda really should have had its inputs checked by the calling function already. However, since all of libgeda's code is user-facing -- we don't have any private headers or the like -- this point is rather moot. In addition, "succeeding" doesn't preclude printing messages to the effect of, "Someone's playing silly buggers but I'm going to try my best anyway." g_critical() should be used for this. One example would be when an unknown object type is encountered; at the moment, libgeda often kills the program by calling g_assert_not_reached(), when often it would be valid to continue by logging a critical message and then skipping over the offending object.
Secondly, "If failure is inevitable, fail gracefully." Failing gracefully requires no dangerous side-effects from the failure. If possible, the system should be returned to its prior state. This often requires that user data needs to be checked before doing anything destructive, possibly at the expense of some CPU time.
GError is a nice mechanism in that it allows errors to be ignored if necessary. A good example of when it should be used would be in code which reads and writes files; because GLib's file access code already uses GError extensively, this would not be hard to implement.
Finally, "Assume that libgeda works." Similarly to rule #1, what is meant here is that libgeda functions should check their own behaviour. If they do so, there is no need for libgeda functions which call them to check again -- it's a waste of CPU time and developer effort.
So, given the above points, when is it appropriate to use g_assert()? It would not be appropriate to use it to check the arguments passed to a function, but it would be valid to use it to check that the function has successfully done what it is supposed to before returning a result. For instance, when a complex algorithm is in use, putting some assertions in to make sure that the algorithm actually does what you think it does might be a very good idea.
Of course, this has lead to a number of action items in terms of libgeda refactoring:
As usual, I'd be interested to hear peoples' thoughts on this. Please let me know on the -dev list or by e-mail.