Prerequestite libraries: OSlib
/* * Copyright (C) Stewart Brodie, 1996 * * Use freely, no liability accepted for any losses, etc. * * This file: moduleversion.h * * This code performs the first half of a *RMEnsure procedure - rather * than executing an arbitrary *-command, the version number is (optionally) * returned and a flag indicating whether the module was found, older than * same as, or newer than the version specified. * */ #ifndef _moduleversion_h_included #define _moduleversion_h_included #ifdef __cplusplus extern "C" { #endif typedef enum { moduleversion_NOT_FOUND, moduleversion_TOO_OLD, moduleversion_MATCH, moduleversion_NEWER } module_version_flags; typedef struct { int major; int minor; } module_version_number; /* Determine the presence/absence and optionally the version number of * a RISC OS module. * * Parameters: * name: module name, cannot be NULL * wanted: pointer to a structure containing minimum acceptable version * (may be NULL if looking for any version - treated as 0.00) * present: pointer to a structure in which to store the version number * of the module if it was found (and if it is non-NULL). * Structure is not updated if function returns NOT_FOUND * * Returns: * one of the values of module_version_flags defined above. * The `present' structure is not touched if this value is * moduleversion_TOO_OLD, but is with any other result */ extern module_version_flags moduleversion_check(const char */*name*/, module_version_number */*wanted*/, module_version_number */*present*/); #ifdef __cplusplus } #endif #endif
/* * Copyright (C) Stewart Brodie, 1996 * * Use freely, no liability accepted for any losses, etc. * * This file: moduleversion.c * */ #include "moduleversion.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include "OS:osmodule.h" module_version_flags moduleversion_check(const char *name, module_version_number *wanted, module_version_number *present) { byte *code; const int *module_header; const char *help_string; int count; module_version_number want = { 0,0 }; module_version_number found = { -1, -1 }; module_version_flags flags = moduleversion_NOT_FOUND; os_error *err = xosmodule_lookup(name, NULL, NULL, &code, NULL, NULL); if (err) { return flags; } if (wanted) want = *wanted; module_header = (const int *)code; if (!module_header[5]) { return flags; } help_string = (char *)(code + module_header[5]); count = 0; while (*help_string) { if (*help_string == '\t') { ++help_string; count = (count + 8) & ~7; continue; } if (count >= 16 && isdigit(*help_string)) { /* think we've found it */ if (help_string[1] == '.' || (isdigit(help_string[1]) && help_string[2] == '.')) { /* We're pretty sure now */ count = sscanf(help_string, "%u.%u", &found.major, &found.minor); if (count != 2) { return flags; } if (present) *present = found; if (found.major > want.major) { return moduleversion_NEWER; } if (found.major < want.major) { return moduleversion_TOO_OLD; } if (found.minor > want.minor) { return moduleversion_NEWER; } if (found.minor < want.minor) { return moduleversion_TOO_OLD; } return moduleversion_MATCH; } /* Doesn't look like a version number .. carry on */ } ++help_string; ++count; } /* We reached the end of the string - we are now confused */ return moduleversion_NOT_FOUND; } #ifdef TEST int main(int argc, char **argv) { module_version_flags flags; module_version_number wanted, present; ++argv; --argc; for (;argc >= 2;argc-=2,argv+=2) { if (sscanf(argv[1], "%u.%u", &wanted.major, &wanted.minor) != 2) continue; flags = moduleversion_check(argv[0], &wanted, &present); (void) printf("%s: ", argv[0]); switch (flags) { case moduleversion_NOT_FOUND: (void) printf("not found\n"); break; case moduleversion_MATCH: (void) printf("%u.%02u found - exact version match\n", present.major, present.minor); break; case moduleversion_TOO_OLD: (void) printf("%u.%02u found - too old\n", present.major, present.minor); break; case moduleversion_NEWER: (void) printf("%u.%02u found - newer than minimum\n", present.major, present.minor); break; } } return 0; } #endif