Version and feature detection between operating system branches
Andrew Hodgkinson (6) 465 posts |
Lately RISC OS Open and RISCOS Limited have been discussing how to tackle the problem of feature detection and version control and at ROOL we thought we’d open this up to the community for wider discussion and suggestions. There seem to be two main problems.
There are plenty of ad-hoc solutions to feature checking and arguably any good code, application or module, should withstand error conditions and exit cleanly rather than crash. It is still far better to provide a deterministic, reliable and common API for this than rely upon lots of different version query interfaces and hope that all possible error conditions are accounted for. 1. OS branch checkingIn some respects, problem (1) can be tackled by relying on the solution to problem (2). A module which needs particular features from the underlying OS in order to run can use the same mechanism as anything else to check for this in its initialisation handler and refuse to start if the required features are missing. That doesn’t cover everything though. While we do not want to prevent users of one OS branch from loading modules made on another, it may be useful for branches to be identified by some token and for modules which have a “preference for” / were designed for a particular branch to be able to say so. The best idea we’ve come up with so far is to use a spare flags word (e.g. the “is 32-bit” word currently only has a single flags bit in use) which identifies a further module header field that states a preference for an OS branch. It would be unwise to assume there will only ever be two branches (who knows what the future may hold) but at the same time, allowing for more than a 32-bit word identifying the branch seems excessive. Examples might include “ROOL” or “ROL00” (although they’re a bit too similar for comfort!). The accompanying OS branch would of course know its own 32-bit identifier and be able to match this against modules where necessary. In the event that “something” (e.g. some kind of 2. Feature detectionIn a similar manner to feature set detection on some other operating systems, we might choose to identify features based on a feature string of (for example) comma-separated tags. A new command to replace A new As in section (1) above, if the OS had a choice of modules matching a requested feature set it would choose a combination of the best match to its own branch identifier and highest version number. Footnote: An Feature string allocationA big problem with feature detection is in knowing which features you can check for in the first place! Although module authors could document them as part of their API, there would be a risk of OS branches using the same feature tag to mean something different. Conversely, making tags branch-specific defeats the idea of being able to check for a feature which may be available on both versions of the OS, assuming a compatible API in both cases, which leaves us back at square one when it comes to writing “cross-branch” code. One possible solution to this is to have tag strings allocated, so that documentation on what a tag means for a particular module is held centrally and it’s easy for a programmer to find the available tags for a given task. This would require a neutral allocation agency and independent, public read access allocations database. On the other hand, you might think that it’s so unlikely to have two independently implemented features in different operating systems coded to the same API that having cross-branch feature identification tags is useless – we may well be able to count on the fingers of no hands (!) the number of feature tags that would actually fall into such a category. It’s not just about branchesThere may be a time in future when the existing branches of RISC OS merge in whole or in part, rather than new branches being created. In any event, the API ought to be available on existing (branched) OS versions, a decent API for feature identification is long overdue regardless of branches and anything which was robust enough to cope with multiple branches would surely be easily sufficient for a unified code base. Ongoing discussionAny comments on the above? Different ideas or amendments? Questions? Post a reply and let us know your thoughts! |
Steve Revill (20) 1361 posts |
I’d just like to clarify a couple of points. Current modules have a flags word of which only bit zero has a meaning (the module is 32-bit safe). We could define a new flag bit to indicate that some known offset in the module header is a four byte ID identifying the OS branch. Or, if we assume there will never be more than two branches, that flag bit could itself be the indicator. Any module which doesn’t have a flags word is assumed to pre-date the split so we might need to fall back to the old version number check. Modules which do have a flags word but predate this spec would then fall into one or other camp by default – which is probably a good reason not to use the flag bit as a direct indicator. Finally, adding an OS_Module reason code could quite easily be retro fitted into older versions of the OS - there are examples of similar extensions provided by the “CallASWI” module – which does a lot of that sort of thing. The one thing we can’t keep doing is RMEnsure UtilityModule x.xx ! |