diff options
| author | cashmere <cashmere@autistici.org> | 2026-09-04 09:05:24 +0200 |
|---|---|---|
| committer | cashmere <cashmere@autistici.org> | 2026-09-04 09:05:24 +0200 |
| commit | 4f49b16079b27d7ce633619e4cddfdf2bffbc952 (patch) | |
| tree | c296c1e7f3c3e2f6859c6d3a1b1b208779b89679 /tools/mkversion.c | |
| download | relic-master.tar.gz | |
Diffstat (limited to 'tools/mkversion.c')
| -rw-r--r-- | tools/mkversion.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/tools/mkversion.c b/tools/mkversion.c new file mode 100644 index 0000000..005babd --- /dev/null +++ b/tools/mkversion.c @@ -0,0 +1,218 @@ +/* +** This C program generates the "VERSION.h" header file from information +** extracted out of the "manifest", "manifest.uuid", and "VERSION" files. +** Call this program with three arguments: +** +** ./a.out manifest.uuid manifest VERSION +** +** Note that the manifest.uuid and manifest files are generated by Fossil. +** +** The output becomes the "VERSION.h" file. The output is a C-language +** header that contains #defines for various properties of the build: +** +** MANIFEST_UUID These values are text strings that +** MANIFEST_VERSION identify the Fossil check-in to which +** the source tree belongs. They do not +** take into account any uncommitted edits. +** +** FOSSIL_BUILD_HASH A hexadecimal string that is a strong hash +** of the MANIFEST_UUID together with the +** current time of the build. We normally want +** this to be different on each build, as the +** value is used to expire ETag: fields in +** HTTP requests. But if you need to do +** repeatable byte-for-byte identical builds, +** add the -DFOSSIL_BUILD_EPOCH=n option. +** +** MANIFEST_DATE The date/time of the source-code check-in +** MANIFEST_YEAR in various formats. +** MANIFEST_NUMERIC_DATE +** MANIFEST_NUMERIC_TIME +** +** RELEASE_VERSION The version number (from the VERSION source +** RELEASE_VERSION_NUMBER file) in various format. +** RELEASE_RESOURCE_VERSION +** +** New #defines may be added in the future. +*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <time.h> + +#if defined(_MSC_VER) && (_MSC_VER < 1800) /* MSVS 2013 */ +# define strtoll _strtoi64 +#endif + +static FILE *open_for_reading(const char *zFilename){ + FILE *f = fopen(zFilename, "r"); + if( f==0 ){ + fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename); + exit(1); + } + return f; +} + +/* +** Given an arbitrary-length input string key zIn, generate +** an N-byte hexadecimal hash of that string into zOut. +*/ +static void hash(const char *zIn, int N, char *zOut){ + unsigned char i, j, t; + int m, n; + unsigned char s[256]; + for(m=0; m<256; m++){ s[m] = m; } + for(j=0, m=n=0; m<256; m++, n++){ + j += s[m] + zIn[n]; + if( zIn[n]==0 ){ n = -1; } + t = s[j]; + s[j] = s[m]; + s[m] = t; + } + i = j = 0; + for(n=0; n<N-2; n+=2){ + i++; + t = s[i]; + j += t; + s[i] = s[j]; + s[j] = t; + t += s[i]; + zOut[n] = "0123456789abcdef"[(t>>4)&0xf]; + zOut[n+1] = "0123456789abcdef"[t&0xf]; + } + zOut[n] = 0; +} + +/* Local strcpy() clone to squelch an unwarranted warning from OpenBSD. */ +static void local_strcpy(char *dest, const char *src){ + while( (*(dest++) = *(src++))!=0 ){} +} + +int main(int argc, char *argv[]){ + FILE *m,*u,*v; + char *z; +#if defined(__DMC__) /* e.g. 0x857 */ + int i = 0; +#endif + int j = 0, x = 0, d = 0; + size_t n; + int vn[3]; + char b[1000]; + char vx[1000]; + if( argc!=4 ){ + fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]); + exit(1); + } + memset(b,0,sizeof(b)); + memset(vx,0,sizeof(vx)); + u = open_for_reading(argv[1]); + if( fgets(b, sizeof(b)-1,u)==0 ){ + fprintf(stderr, "malformed manifest.uuid file: %s\n", argv[1]); + exit(1); + } + fclose(u); + for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} + *z = 0; + printf("#define MANIFEST_UUID \"%s\"\n",b); + printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b); + n = strlen(b); + if( n + 50 < sizeof(b) ){ +#ifdef FOSSIL_BUILD_EPOCH +#define str(s) #s + snprintf(b+n, sizeof(b)-n, + "%d", (int)strtoll(str(FOSSIL_BUILD_EPOCH), 0, 10)); +#else + const char *zEpoch = getenv("SOURCE_DATE_EPOCH"); + if( zEpoch && isdigit(zEpoch[0]) ){ + snprintf(b+n, sizeof(b)-n, "%d", (int)strtoll(zEpoch, 0, 10)); + }else{ + snprintf(b+n, sizeof(b)-n, "%d", (int)time(0)); + } +#endif + hash(b,33,vx); + printf("#define FOSSIL_BUILD_HASH \"%s\"\n", vx); + } + m = open_for_reading(argv[2]); + while(b == fgets(b, sizeof(b)-1,m)){ + if(0 == strncmp("D ",b,2)){ + int k, n; + char zDateNum[30]; + printf("#define MANIFEST_DATE \"%.10s %.8s\"\n",b+2,b+13); + printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2); + n = 0; + for(k=0; k<10; k++){ + if( isdigit(b[k+2]) ) zDateNum[n++] = b[k+2]; + } + zDateNum[n] = 0; + printf("#define MANIFEST_NUMERIC_DATE %s\n", zDateNum); + n = 0; + for(k=0; k<8; k++){ + if( isdigit(b[k+13]) ) zDateNum[n++] = b[k+13]; + } + zDateNum[n] = 0; + for(k=0; zDateNum[k]=='0'; k++){} + printf("#define MANIFEST_NUMERIC_TIME %s\n", zDateNum+k); + } + } + fclose(m); + v = open_for_reading(argv[3]); + if( fgets(b, sizeof(b)-1,v)==0 ){ + fprintf(stderr, "malformed VERSION file: %s\n", argv[3]); + exit(1); + } + fclose(v); + for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} + *z = 0; + printf("#define RELEASE_VERSION \"%s\"\n", b); + z=b; + vn[0] = vn[1] = vn[2] = 0; + while(1){ + if( z[0]>='0' && z[0]<='9' ){ + x = x*10 + z[0] - '0'; + }else{ + if( j<3 ) vn[j++] = x; + x = 0; + if( z[0]==0 ) break; + } + z++; + } + for(z=vx; z[0]=='0'; z++){} + printf("#define RELEASE_VERSION_NUMBER %d%02d%02d\n", vn[0], vn[1], vn[2]); + memset(vx,0,sizeof(vx)); + local_strcpy(vx,b); + for(z=vx; z[0]; z++){ + if( z[0]=='-' ){ + z[0] = 0; + break; + } + if( z[0]!='.' ) continue; + if ( d<3 ){ + z[0] = ','; + d++; + }else{ + z[0] = '\0'; + break; + } + } + printf("#define RELEASE_RESOURCE_VERSION %s", vx); + while( d<3 ){ printf(",0"); d++; } + printf("\n"); +#if defined(__DMC__) /* e.g. 0x857 */ + d = (__DMC__ & 0xF00) >> 8; /* major */ + x = (__DMC__ & 0x0F0) >> 4; /* minor */ + i = (__DMC__ & 0x00F); /* revision */ + printf("#define COMPILER_VERSION \"%d.%d.%d\"\n", d, x, i); +#elif defined(__POCC__) /* e.g. 700 */ + d = (__POCC__ / 100); /* major */ + x = (__POCC__ % 100); /* minor */ + printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x); +#elif defined(_MSC_VER) /* e.g. 1800 */ + /* _MSC_FULL_VER also defined, e.g. 193030709 */ + d = (_MSC_VER / 100); /* major */ + x = (_MSC_VER % 100); /* minor */ + printf("#define COMPILER_VERSION \"%d.%02d.", d, x); + printf("%05d\"\n",(int)(_MSC_FULL_VER % 100000)); /* build (patch) */ +#endif + return 0; +} |
