Fossil SCM

fossil-scm / tools / mkversion.c
Blame History Raw 219 lines
1
/*
2
** This C program generates the "VERSION.h" header file from information
3
** extracted out of the "manifest", "manifest.uuid", and "VERSION" files.
4
** Call this program with three arguments:
5
**
6
** ./a.out manifest.uuid manifest VERSION
7
**
8
** Note that the manifest.uuid and manifest files are generated by Fossil.
9
**
10
** The output becomes the "VERSION.h" file. The output is a C-language
11
** header that contains #defines for various properties of the build:
12
**
13
** MANIFEST_UUID These values are text strings that
14
** MANIFEST_VERSION identify the Fossil check-in to which
15
** the source tree belongs. They do not
16
** take into account any uncommitted edits.
17
**
18
** FOSSIL_BUILD_HASH A hexadecimal string that is a strong hash
19
** of the MANIFEST_UUID together with the
20
** current time of the build. We normally want
21
** this to be different on each build, as the
22
** value is used to expire ETag: fields in
23
** HTTP requests. But if you need to do
24
** repeatable byte-for-byte identical builds,
25
** add the -DFOSSIL_BUILD_EPOCH=n option.
26
**
27
** MANIFEST_DATE The date/time of the source-code check-in
28
** MANIFEST_YEAR in various formats.
29
** MANIFEST_NUMERIC_DATE
30
** MANIFEST_NUMERIC_TIME
31
**
32
** RELEASE_VERSION The version number (from the VERSION source
33
** RELEASE_VERSION_NUMBER file) in various format.
34
** RELEASE_RESOURCE_VERSION
35
**
36
** New #defines may be added in the future.
37
*/
38
#include <stdio.h>
39
#include <string.h>
40
#include <stdlib.h>
41
#include <ctype.h>
42
#include <time.h>
43
44
#if defined(_MSC_VER) && (_MSC_VER < 1800) /* MSVS 2013 */
45
# define strtoll _strtoi64
46
#endif
47
48
static FILE *open_for_reading(const char *zFilename){
49
FILE *f = fopen(zFilename, "r");
50
if( f==0 ){
51
fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename);
52
exit(1);
53
}
54
return f;
55
}
56
57
/*
58
** Given an arbitrary-length input string key zIn, generate
59
** an N-byte hexadecimal hash of that string into zOut.
60
*/
61
static void hash(const char *zIn, int N, char *zOut){
62
unsigned char i, j, t;
63
int m, n;
64
unsigned char s[256];
65
for(m=0; m<256; m++){ s[m] = m; }
66
for(j=0, m=n=0; m<256; m++, n++){
67
j += s[m] + zIn[n];
68
if( zIn[n]==0 ){ n = -1; }
69
t = s[j];
70
s[j] = s[m];
71
s[m] = t;
72
}
73
i = j = 0;
74
for(n=0; n<N-2; n+=2){
75
i++;
76
t = s[i];
77
j += t;
78
s[i] = s[j];
79
s[j] = t;
80
t += s[i];
81
zOut[n] = "0123456789abcdef"[(t>>4)&0xf];
82
zOut[n+1] = "0123456789abcdef"[t&0xf];
83
}
84
zOut[n] = 0;
85
}
86
87
/* Local strcpy() clone to squelch an unwarranted warning from OpenBSD. */
88
static void local_strcpy(char *dest, const char *src){
89
while( (*(dest++) = *(src++))!=0 ){}
90
}
91
92
int main(int argc, char *argv[]){
93
FILE *m,*u,*v;
94
char *z;
95
#if defined(__DMC__) /* e.g. 0x857 */
96
int i = 0;
97
#endif
98
int j = 0, x = 0, d = 0;
99
size_t n;
100
int vn[3];
101
char b[1000];
102
char vx[1000];
103
if( argc!=4 ){
104
fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]);
105
exit(1);
106
}
107
memset(b,0,sizeof(b));
108
memset(vx,0,sizeof(vx));
109
u = open_for_reading(argv[1]);
110
if( fgets(b, sizeof(b)-1,u)==0 ){
111
fprintf(stderr, "malformed manifest.uuid file: %s\n", argv[1]);
112
exit(1);
113
}
114
fclose(u);
115
for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
116
*z = 0;
117
printf("#define MANIFEST_UUID \"%s\"\n",b);
118
printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b);
119
n = strlen(b);
120
if( n + 50 < sizeof(b) ){
121
#ifdef FOSSIL_BUILD_EPOCH
122
#define str(s) #s
123
snprintf(b+n, sizeof(b)-n,
124
"%d", (int)strtoll(str(FOSSIL_BUILD_EPOCH), 0, 10));
125
#else
126
const char *zEpoch = getenv("SOURCE_DATE_EPOCH");
127
if( zEpoch && isdigit(zEpoch[0]) ){
128
snprintf(b+n, sizeof(b)-n, "%d", (int)strtoll(zEpoch, 0, 10));
129
}else{
130
snprintf(b+n, sizeof(b)-n, "%d", (int)time(0));
131
}
132
#endif
133
hash(b,33,vx);
134
printf("#define FOSSIL_BUILD_HASH \"%s\"\n", vx);
135
}
136
m = open_for_reading(argv[2]);
137
while(b == fgets(b, sizeof(b)-1,m)){
138
if(0 == strncmp("D ",b,2)){
139
int k, n;
140
char zDateNum[30];
141
printf("#define MANIFEST_DATE \"%.10s %.8s\"\n",b+2,b+13);
142
printf("#define MANIFEST_YEAR \"%.4s\"\n",b+2);
143
n = 0;
144
for(k=0; k<10; k++){
145
if( isdigit(b[k+2]) ) zDateNum[n++] = b[k+2];
146
}
147
zDateNum[n] = 0;
148
printf("#define MANIFEST_NUMERIC_DATE %s\n", zDateNum);
149
n = 0;
150
for(k=0; k<8; k++){
151
if( isdigit(b[k+13]) ) zDateNum[n++] = b[k+13];
152
}
153
zDateNum[n] = 0;
154
for(k=0; zDateNum[k]=='0'; k++){}
155
printf("#define MANIFEST_NUMERIC_TIME %s\n", zDateNum+k);
156
}
157
}
158
fclose(m);
159
v = open_for_reading(argv[3]);
160
if( fgets(b, sizeof(b)-1,v)==0 ){
161
fprintf(stderr, "malformed VERSION file: %s\n", argv[3]);
162
exit(1);
163
}
164
fclose(v);
165
for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){}
166
*z = 0;
167
printf("#define RELEASE_VERSION \"%s\"\n", b);
168
z=b;
169
vn[0] = vn[1] = vn[2] = 0;
170
while(1){
171
if( z[0]>='0' && z[0]<='9' ){
172
x = x*10 + z[0] - '0';
173
}else{
174
if( j<3 ) vn[j++] = x;
175
x = 0;
176
if( z[0]==0 ) break;
177
}
178
z++;
179
}
180
for(z=vx; z[0]=='0'; z++){}
181
printf("#define RELEASE_VERSION_NUMBER %d%02d%02d\n", vn[0], vn[1], vn[2]);
182
memset(vx,0,sizeof(vx));
183
local_strcpy(vx,b);
184
for(z=vx; z[0]; z++){
185
if( z[0]=='-' ){
186
z[0] = 0;
187
break;
188
}
189
if( z[0]!='.' ) continue;
190
if ( d<3 ){
191
z[0] = ',';
192
d++;
193
}else{
194
z[0] = '\0';
195
break;
196
}
197
}
198
printf("#define RELEASE_RESOURCE_VERSION %s", vx);
199
while( d<3 ){ printf(",0"); d++; }
200
printf("\n");
201
#if defined(__DMC__) /* e.g. 0x857 */
202
d = (__DMC__ & 0xF00) >> 8; /* major */
203
x = (__DMC__ & 0x0F0) >> 4; /* minor */
204
i = (__DMC__ & 0x00F); /* revision */
205
printf("#define COMPILER_VERSION \"%d.%d.%d\"\n", d, x, i);
206
#elif defined(__POCC__) /* e.g. 700 */
207
d = (__POCC__ / 100); /* major */
208
x = (__POCC__ % 100); /* minor */
209
printf("#define COMPILER_VERSION \"%d.%02d\"\n", d, x);
210
#elif defined(_MSC_VER) /* e.g. 1800 */
211
/* _MSC_FULL_VER also defined, e.g. 193030709 */
212
d = (_MSC_VER / 100); /* major */
213
x = (_MSC_VER % 100); /* minor */
214
printf("#define COMPILER_VERSION \"%d.%02d.", d, x);
215
printf("%05d\"\n",(int)(_MSC_FULL_VER % 100000)); /* build (patch) */
216
#endif
217
return 0;
218
}
219

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button