Fossil SCM
Shift the computation of the hash returned by fossil_exe_id() from run-time to compile-time.
Commit
22fc5a792ce12a2a200b72138a099eb4bc427f14e58b5d0a0988f28bb42d1204
Parent
54a8243bf5e4b24…
2 files changed
+9
-11
+38
+9
-11
| --- src/etag.c | ||
| +++ src/etag.c | ||
| @@ -71,23 +71,21 @@ | ||
| 71 | 71 | |
| 72 | 72 | /* |
| 73 | 73 | ** Return a hash that changes every time the Fossil source code is |
| 74 | 74 | ** rebuilt. |
| 75 | 75 | ** |
| 76 | -** The current implementation is a hash of MANIFEST_UUID, __DATE__, and | |
| 77 | -** __TIME__. But this might change in the future if we think of a better | |
| 78 | -** way to compute an identifier that changes with each build. | |
| 76 | +** The FOSSIL_BUILD_HASH string that is returned here gets computed by | |
| 77 | +** the mkversion utility program. The result is a hash of MANIFEST_UUID | |
| 78 | +** and the unix timestamp for when the mkversion utility program is run. | |
| 79 | +** | |
| 80 | +** During development rebuilds, if you need the source code id to change | |
| 81 | +** in order to invalidate caches, simply "touch" the "manifest" file in | |
| 82 | +** the top of the source directory prior to running "make" and a new | |
| 83 | +** FOSSIL_BUILD_HASH will be generated automatically. | |
| 79 | 84 | */ |
| 80 | 85 | const char *fossil_exe_id(void){ |
| 81 | - static char zExecId[33]; | |
| 82 | - if( zExecId[0]==0 ){ | |
| 83 | - Blob x; | |
| 84 | - blob_init(&x, MANIFEST_UUID "," __DATE__ "," __TIME__, -1); | |
| 85 | - md5sum_blob(&x, &x); | |
| 86 | - memcpy(zExecId, x.aData, 32); | |
| 87 | - } | |
| 88 | - return zExecId; | |
| 86 | + return FOSSIL_BUILD_HASH; | |
| 89 | 87 | } |
| 90 | 88 | |
| 91 | 89 | /* |
| 92 | 90 | ** Generate an ETag |
| 93 | 91 | */ |
| 94 | 92 |
| --- src/etag.c | |
| +++ src/etag.c | |
| @@ -71,23 +71,21 @@ | |
| 71 | |
| 72 | /* |
| 73 | ** Return a hash that changes every time the Fossil source code is |
| 74 | ** rebuilt. |
| 75 | ** |
| 76 | ** The current implementation is a hash of MANIFEST_UUID, __DATE__, and |
| 77 | ** __TIME__. But this might change in the future if we think of a better |
| 78 | ** way to compute an identifier that changes with each build. |
| 79 | */ |
| 80 | const char *fossil_exe_id(void){ |
| 81 | static char zExecId[33]; |
| 82 | if( zExecId[0]==0 ){ |
| 83 | Blob x; |
| 84 | blob_init(&x, MANIFEST_UUID "," __DATE__ "," __TIME__, -1); |
| 85 | md5sum_blob(&x, &x); |
| 86 | memcpy(zExecId, x.aData, 32); |
| 87 | } |
| 88 | return zExecId; |
| 89 | } |
| 90 | |
| 91 | /* |
| 92 | ** Generate an ETag |
| 93 | */ |
| 94 |
| --- src/etag.c | |
| +++ src/etag.c | |
| @@ -71,23 +71,21 @@ | |
| 71 | |
| 72 | /* |
| 73 | ** Return a hash that changes every time the Fossil source code is |
| 74 | ** rebuilt. |
| 75 | ** |
| 76 | ** The FOSSIL_BUILD_HASH string that is returned here gets computed by |
| 77 | ** the mkversion utility program. The result is a hash of MANIFEST_UUID |
| 78 | ** and the unix timestamp for when the mkversion utility program is run. |
| 79 | ** |
| 80 | ** During development rebuilds, if you need the source code id to change |
| 81 | ** in order to invalidate caches, simply "touch" the "manifest" file in |
| 82 | ** the top of the source directory prior to running "make" and a new |
| 83 | ** FOSSIL_BUILD_HASH will be generated automatically. |
| 84 | */ |
| 85 | const char *fossil_exe_id(void){ |
| 86 | return FOSSIL_BUILD_HASH; |
| 87 | } |
| 88 | |
| 89 | /* |
| 90 | ** Generate an ETag |
| 91 | */ |
| 92 |
+38
| --- src/mkversion.c | ||
| +++ src/mkversion.c | ||
| @@ -9,27 +9,59 @@ | ||
| 9 | 9 | */ |
| 10 | 10 | #include <stdio.h> |
| 11 | 11 | #include <string.h> |
| 12 | 12 | #include <stdlib.h> |
| 13 | 13 | #include <ctype.h> |
| 14 | +#include <time.h> | |
| 14 | 15 | |
| 15 | 16 | static FILE *open_for_reading(const char *zFilename){ |
| 16 | 17 | FILE *f = fopen(zFilename, "r"); |
| 17 | 18 | if( f==0 ){ |
| 18 | 19 | fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename); |
| 19 | 20 | exit(1); |
| 20 | 21 | } |
| 21 | 22 | return f; |
| 22 | 23 | } |
| 24 | + | |
| 25 | +/* | |
| 26 | +** Given an arbitrary-length input string key zIn, generate | |
| 27 | +** an N-byte hexadecimal hash of that string into zOut. | |
| 28 | +*/ | |
| 29 | +static void hash(const char *zIn, int N, char *zOut){ | |
| 30 | + unsigned char i, j, t; | |
| 31 | + int m, n; | |
| 32 | + unsigned char s[256]; | |
| 33 | + for(m=0; m<256; m++){ s[m] = m; } | |
| 34 | + for(j=0, m=n=0; m<256; m++, n++){ | |
| 35 | + j += s[m] + zIn[n]; | |
| 36 | + if( zIn[n]==0 ){ n = -1; } | |
| 37 | + t = s[j]; | |
| 38 | + s[j] = s[m]; | |
| 39 | + s[m] = t; | |
| 40 | + } | |
| 41 | + i = j = 0; | |
| 42 | + for(n=0; n<N-2; n+=2){ | |
| 43 | + i++; | |
| 44 | + t = s[i]; | |
| 45 | + j += t; | |
| 46 | + s[i] = s[j]; | |
| 47 | + s[j] = t; | |
| 48 | + t += s[i]; | |
| 49 | + zOut[n] = "0123456789abcdef"[(t>>4)&0xf]; | |
| 50 | + zOut[n+1] = "0123456789abcdef"[t&0xf]; | |
| 51 | + } | |
| 52 | + zOut[n] = 0; | |
| 53 | +} | |
| 23 | 54 | |
| 24 | 55 | int main(int argc, char *argv[]){ |
| 25 | 56 | FILE *m,*u,*v; |
| 26 | 57 | char *z; |
| 27 | 58 | #if defined(__DMC__) /* e.g. 0x857 */ |
| 28 | 59 | int i = 0; |
| 29 | 60 | #endif |
| 30 | 61 | int j = 0, x = 0, d = 0; |
| 62 | + size_t n; | |
| 31 | 63 | int vn[3]; |
| 32 | 64 | char b[1000]; |
| 33 | 65 | char vx[1000]; |
| 34 | 66 | if( argc!=4 ){ |
| 35 | 67 | fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]); |
| @@ -45,10 +77,16 @@ | ||
| 45 | 77 | fclose(u); |
| 46 | 78 | for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} |
| 47 | 79 | *z = 0; |
| 48 | 80 | printf("#define MANIFEST_UUID \"%s\"\n",b); |
| 49 | 81 | printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b); |
| 82 | + n = strlen(b); | |
| 83 | + if( n + 50 < sizeof(b) ){ | |
| 84 | + sprintf(b+n, "%d", (int)time(0)); | |
| 85 | + hash(b,33,vx); | |
| 86 | + printf("#define FOSSIL_BUILD_HASH \"%s\"\n", vx); | |
| 87 | + } | |
| 50 | 88 | m = open_for_reading(argv[2]); |
| 51 | 89 | while(b == fgets(b, sizeof(b)-1,m)){ |
| 52 | 90 | if(0 == strncmp("D ",b,2)){ |
| 53 | 91 | int k, n; |
| 54 | 92 | char zDateNum[30]; |
| 55 | 93 |
| --- src/mkversion.c | |
| +++ src/mkversion.c | |
| @@ -9,27 +9,59 @@ | |
| 9 | */ |
| 10 | #include <stdio.h> |
| 11 | #include <string.h> |
| 12 | #include <stdlib.h> |
| 13 | #include <ctype.h> |
| 14 | |
| 15 | static FILE *open_for_reading(const char *zFilename){ |
| 16 | FILE *f = fopen(zFilename, "r"); |
| 17 | if( f==0 ){ |
| 18 | fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename); |
| 19 | exit(1); |
| 20 | } |
| 21 | return f; |
| 22 | } |
| 23 | |
| 24 | int main(int argc, char *argv[]){ |
| 25 | FILE *m,*u,*v; |
| 26 | char *z; |
| 27 | #if defined(__DMC__) /* e.g. 0x857 */ |
| 28 | int i = 0; |
| 29 | #endif |
| 30 | int j = 0, x = 0, d = 0; |
| 31 | int vn[3]; |
| 32 | char b[1000]; |
| 33 | char vx[1000]; |
| 34 | if( argc!=4 ){ |
| 35 | fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]); |
| @@ -45,10 +77,16 @@ | |
| 45 | fclose(u); |
| 46 | for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} |
| 47 | *z = 0; |
| 48 | printf("#define MANIFEST_UUID \"%s\"\n",b); |
| 49 | printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b); |
| 50 | m = open_for_reading(argv[2]); |
| 51 | while(b == fgets(b, sizeof(b)-1,m)){ |
| 52 | if(0 == strncmp("D ",b,2)){ |
| 53 | int k, n; |
| 54 | char zDateNum[30]; |
| 55 |
| --- src/mkversion.c | |
| +++ src/mkversion.c | |
| @@ -9,27 +9,59 @@ | |
| 9 | */ |
| 10 | #include <stdio.h> |
| 11 | #include <string.h> |
| 12 | #include <stdlib.h> |
| 13 | #include <ctype.h> |
| 14 | #include <time.h> |
| 15 | |
| 16 | static FILE *open_for_reading(const char *zFilename){ |
| 17 | FILE *f = fopen(zFilename, "r"); |
| 18 | if( f==0 ){ |
| 19 | fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename); |
| 20 | exit(1); |
| 21 | } |
| 22 | return f; |
| 23 | } |
| 24 | |
| 25 | /* |
| 26 | ** Given an arbitrary-length input string key zIn, generate |
| 27 | ** an N-byte hexadecimal hash of that string into zOut. |
| 28 | */ |
| 29 | static void hash(const char *zIn, int N, char *zOut){ |
| 30 | unsigned char i, j, t; |
| 31 | int m, n; |
| 32 | unsigned char s[256]; |
| 33 | for(m=0; m<256; m++){ s[m] = m; } |
| 34 | for(j=0, m=n=0; m<256; m++, n++){ |
| 35 | j += s[m] + zIn[n]; |
| 36 | if( zIn[n]==0 ){ n = -1; } |
| 37 | t = s[j]; |
| 38 | s[j] = s[m]; |
| 39 | s[m] = t; |
| 40 | } |
| 41 | i = j = 0; |
| 42 | for(n=0; n<N-2; n+=2){ |
| 43 | i++; |
| 44 | t = s[i]; |
| 45 | j += t; |
| 46 | s[i] = s[j]; |
| 47 | s[j] = t; |
| 48 | t += s[i]; |
| 49 | zOut[n] = "0123456789abcdef"[(t>>4)&0xf]; |
| 50 | zOut[n+1] = "0123456789abcdef"[t&0xf]; |
| 51 | } |
| 52 | zOut[n] = 0; |
| 53 | } |
| 54 | |
| 55 | int main(int argc, char *argv[]){ |
| 56 | FILE *m,*u,*v; |
| 57 | char *z; |
| 58 | #if defined(__DMC__) /* e.g. 0x857 */ |
| 59 | int i = 0; |
| 60 | #endif |
| 61 | int j = 0, x = 0, d = 0; |
| 62 | size_t n; |
| 63 | int vn[3]; |
| 64 | char b[1000]; |
| 65 | char vx[1000]; |
| 66 | if( argc!=4 ){ |
| 67 | fprintf(stderr, "Usage: %s manifest.uuid manifest VERSION\n", argv[0]); |
| @@ -45,10 +77,16 @@ | |
| 77 | fclose(u); |
| 78 | for(z=b; z[0] && z[0]!='\r' && z[0]!='\n'; z++){} |
| 79 | *z = 0; |
| 80 | printf("#define MANIFEST_UUID \"%s\"\n",b); |
| 81 | printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b); |
| 82 | n = strlen(b); |
| 83 | if( n + 50 < sizeof(b) ){ |
| 84 | sprintf(b+n, "%d", (int)time(0)); |
| 85 | hash(b,33,vx); |
| 86 | printf("#define FOSSIL_BUILD_HASH \"%s\"\n", vx); |
| 87 | } |
| 88 | m = open_for_reading(argv[2]); |
| 89 | while(b == fgets(b, sizeof(b)-1,m)){ |
| 90 | if(0 == strncmp("D ",b,2)){ |
| 91 | int k, n; |
| 92 | char zDateNum[30]; |
| 93 |