1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
/* libjodycode version checks
*
* Code to embed the libjodycode version info and check against the currently
* linked libjodycode to check for and report incompatibilities
*
* Copyright (C) 2023 by Jody Bruchon <jody@jodybruchon.com>
* Licensed under The MIT License */
#include <stdio.h>
#include <stdlib.h>
#include <libjodycode.h>
#include "libjodycode_check.h"
#include "libjodycode_check_defs.h"
#ifdef JC_TEST
#define JC_TEST_ONLY(a) a
#else
#define JC_TEST_ONLY(a)
#endif
const char *jc_build_version = LIBJODYCODE_VER;
const int jc_build_api_version = LIBJODYCODE_API_VERSION;
const int jc_build_api_featurelevel = LIBJODYCODE_API_FEATURE_LEVEL;
const int jc_build_min_featurelevel = MY_FEATURELEVEL_REQ;
/* API sub-version info array, terminated with 255
* The user-defined part has moved to libjodycode_check_defs.h
* Do not edit this file, edit that one instead! */
/* Build the array data using user definitions */
#if MY_CACHEINFO_REQ == 255
#undef MY_CACHEINFO_REQ
#define MY_CACHEINFO_REQ LIBJODYCODE_CACHEINFO_VER
#endif
#if MY_JODY_HASH_REQ == 255
#undef MY_JODY_HASH_REQ
#define MY_JODY_HASH_REQ LIBJODYCODE_JODY_HASH_VER
#endif
#if MY_OOM_REQ == 255
#undef MY_OOM_REQ
#define MY_OOM_REQ LIBJODYCODE_OOM_VER
#endif
#if MY_PATHS_REQ == 255
#undef MY_PATHS_REQ
#define MY_PATHS_REQ LIBJODYCODE_PATHS_VER
#endif
#if MY_SIZE_SUFFIX_REQ == 255
#undef MY_SIZE_SUFFIX_REQ
#define MY_SIZE_SUFFIX_REQ LIBJODYCODE_SIZE_SUFFIX_VER
#endif
#if MY_SORT_REQ == 255
#undef MY_SORT_REQ
#define MY_SORT_REQ LIBJODYCODE_SORT_VER
#endif
#if MY_STRING_REQ == 255
#undef MY_STRING_REQ
#define MY_STRING_REQ LIBJODYCODE_STRING_VER
#endif
#if MY_STRTOEPOCH_REQ == 255
#undef MY_STRTOEPOCH_REQ
#define MY_STRTOEPOCH_REQ LIBJODYCODE_STRTOEPOCH_VER
#endif
#if MY_WIN_STAT_REQ == 255
#undef MY_WIN_STAT_REQ
#define MY_WIN_STAT_REQ LIBJODYCODE_WIN_STAT_VER
#endif
#if MY_WIN_UNICODE_REQ == 255
#undef MY_WIN_UNICODE_REQ
#define MY_WIN_UNICODE_REQ LIBJODYCODE_WIN_UNICODE_VER
#endif
#if MY_ERROR_REQ == 255
#undef MY_ERROR_REQ
#define MY_ERROR_REQ LIBJODYCODE_ERROR_VER
#endif
#if MY_ALARM_REQ == 255
#undef MY_ALARM_REQ
#define MY_ALARM_REQ LIBJODYCODE_ALARM_VER
#endif
const unsigned char jc_build_api_versiontable[] = {
MY_CACHEINFO_REQ,
MY_JODY_HASH_REQ,
MY_OOM_REQ,
MY_PATHS_REQ,
MY_SIZE_SUFFIX_REQ,
MY_SORT_REQ,
MY_STRING_REQ,
MY_STRTOEPOCH_REQ,
MY_WIN_STAT_REQ,
MY_WIN_UNICODE_REQ,
MY_ERROR_REQ,
MY_ALARM_REQ,
255
};
const char *jc_versiontable_section[] = {
"cacheinfo",
"jody_hash",
"oom",
"paths",
"size_suffix",
"sort",
"string",
"strtoepoch",
"win_stat",
"win_unicode",
"error",
"alarm",
NULL
};
int libjodycode_version_check(int verbose, int bail)
{
const unsigned char * const restrict build = jc_build_api_versiontable;
const unsigned char * const restrict lib = jc_api_versiontable;
int i = 0;
JC_TEST_ONLY(if (verbose > 1) fprintf(stderr, "libjodycode version check test code\n\n");)
/* Force a version dump if requested */
while (build[i] != 255) {
JC_TEST_ONLY(if (verbose > 1) fprintf(stderr, "API %d: %s: builtin ver %u, lib ver %u\n", i, jc_versiontable_section[i], build[i], lib[i]);)
if (build[i] != 0 && (lib[i] == 0 || build[i] != lib[i])) goto incompatible_versiontable;
i++;
}
JC_TEST_ONLY(if (verbose > 1) goto incompatible_versiontable;)
return 0;
incompatible_versiontable:
if (verbose) {
fprintf(stderr, "\n==============================================================================\n");
fprintf(stderr, "internal error: libjodycode on this system is an incompatible version\n\n");
fprintf(stderr, "Currently using libjodycode v%s, API %d, feature level %d\n",
jc_version, jc_api_version, jc_api_featurelevel);
fprintf(stderr, " Built against libjodycode v%s, API %d, feature level %d\n\n",
jc_build_version, jc_build_api_version, jc_build_api_featurelevel);
if (jc_build_min_featurelevel > jc_build_api_featurelevel)
fprintf(stderr, "libjodycode feature level %d is required but linked library is level %d\n",
jc_build_min_featurelevel, jc_build_api_featurelevel);
if (lib[i] == 0) fprintf(stderr, "API sections are missing in libjodycode; it's probably too old.\n");
else fprintf(stderr, "The first incompatible API section found is '%s' (want v%d, got v%d).\n",
jc_versiontable_section[i], build[i], lib[i]);
fprintf(stderr, "==============================================================================\n\n");
fprintf(stderr, "\nUpdate libjodycode on your system and try again. If you continue to get this\n");
fprintf(stderr, "error, contact the package or distribution maintainer. If all else fails, send\n");
fprintf(stderr, "an email to jody@jodybruchon.com for help (but only as a last resort, please.)\n\n");
}
if (bail) exit(EXIT_FAILURE);
return 1;
}
#ifdef JC_TEST
int main(void)
{
libjodycode_version_check(2, 0);
return 0;
}
#endif
|