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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 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;
}
|