int nlevels = 2;
char *input_base;
char *tmp;
+ struct mdfour hash;
+
if ((s = getenv("CCACHE_NLEVELS"))) {
nlevels = atoi(s);
if (nlevels > 8) nlevels = 8;
}
- hash_start();
+ hash_start(&hash);
/* when we are doing the unifying tricks we need to include
the input file name in the hash to get the warnings right */
if (enable_unify) {
- hash_string(input_file);
+ hash_string(&hash, input_file);
}
/* we have to hash the extension, as a .i file isn't treated the same
by the compiler as a .ii file */
- hash_string(i_extension);
+ hash_string(&hash, i_extension);
/* first the arguments */
for (i=1;i<args->argc;i++) {
stat(args->argv[i]+8, &st) == 0) {
/* if given a explicit specs file, then hash that file, but
don't include the path to it in the hash */
- hash_file(args->argv[i]+8);
+ hash_file(&hash, args->argv[i]+8);
continue;
}
/* all other arguments are included in the hash */
- hash_string(args->argv[i]);
+ hash_string(&hash, args->argv[i]);
}
/* the compiler driver size and date. This is a simple minded way
/* also include the hash of the compiler name - as some compilers
use hard links and behave differently depending on the real name */
if (st.st_nlink > 1) {
- hash_string(str_basename(args->argv[0]));
+ hash_string(&hash, str_basename(args->argv[0]));
}
if (getenv("CCACHE_HASH_COMPILER")) {
- hash_file(args->argv[0]);
+ hash_file(&hash, args->argv[0]);
} else if (!getenv("CCACHE_NOHASH_SIZE_MTIME")) {
- hash_int(st.st_size);
- hash_int(st.st_mtime);
+ hash_int(&hash, st.st_size);
+ hash_int(&hash, st.st_mtime);
}
/* possibly hash the current working directory */
if (getenv("CCACHE_HASHDIR")) {
char *cwd = gnu_getcwd();
if (cwd) {
- hash_string(cwd);
+ hash_string(&hash, cwd);
free(cwd);
}
}
as it gives the wrong line numbers for warnings. Pity.
*/
if (!enable_unify) {
- hash_file(path_stdout);
+ hash_file(&hash, path_stdout);
} else {
- if (unify_hash(path_stdout) != 0) {
+ if (unify_hash(&hash, path_stdout) != 0) {
stats_update(STATS_ERROR);
failed();
}
}
- hash_file(path_stderr);
+ hash_file(&hash, path_stderr);
i_tmpfile = path_stdout;
/* we use a N level subdir for the cache path to reduce the impact
on filesystems which are slow for large directories
*/
- s = hash_result();
+ s = hash_result(&hash);
x_asprintf(&hash_dir, "%s/%c", cache_dir, s[0]);
x_asprintf(&stats_file, "%s/stats", hash_dir);
for (i=1; i<nlevels; i++) {
#include "mdfour.h"
-void hash_start(void);
-void hash_string(const char *s);
-void hash_int(int x);
-void hash_file(const char *fname);
-char *hash_result(void);
-void hash_buffer(const char *s, int len);
+void hash_start(struct mdfour *md);
+void hash_string(struct mdfour *md, const char *s);
+void hash_int(struct mdfour *md, int x);
+void hash_file(struct mdfour *md, const char *fname);
+char *hash_result(struct mdfour *md);
+void hash_buffer(struct mdfour *md, const char *s, int len);
void cc_log(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
void fatal(const char *msg);
void display_size(unsigned v);
void stats_set_sizes(const char *dir, size_t num_files, size_t total_size);
-int unify_hash(const char *fname);
+int unify_hash(struct mdfour *hash, const char *fname);
#ifndef HAVE_VASPRINTF
int vasprintf(char **, const char *, va_list) ATTR_FORMAT(printf, 2, 0);
#include "ccache.h"
-static struct mdfour md;
-
-void hash_buffer(const char *s, int len)
+void hash_buffer(struct mdfour *md, const char *s, int len)
{
- mdfour_update(&md, (unsigned char *)s, len);
+ mdfour_update(md, (unsigned char *)s, len);
}
-void hash_start(void)
+void hash_start(struct mdfour *md)
{
- mdfour_begin(&md);
+ mdfour_begin(md);
}
-void hash_string(const char *s)
+void hash_string(struct mdfour *md, const char *s)
{
- hash_buffer(s, strlen(s));
+ hash_buffer(md, s, strlen(s));
}
-void hash_int(int x)
+void hash_int(struct mdfour *md, int x)
{
- hash_buffer((char *)&x, sizeof(x));
+ hash_buffer(md, (char *)&x, sizeof(x));
}
/* add contents of a file to the hash */
-void hash_file(const char *fname)
+void hash_file(struct mdfour *md, const char *fname)
{
char buf[1024];
int fd, n;
}
while ((n = read(fd, buf, sizeof(buf))) > 0) {
- hash_buffer(buf, n);
+ hash_buffer(md, buf, n);
}
close(fd);
}
/* return the hash result as a static string */
-char *hash_result(void)
+char *hash_result(struct mdfour *md)
{
unsigned char sum[16];
static char ret[53];
int i;
- hash_buffer(NULL, 0);
- mdfour_result(&md, sum);
+ hash_buffer(md, NULL, 0);
+ mdfour_result(md, sum);
for (i=0;i<16;i++) {
sprintf(&ret[i*2], "%02x", (unsigned)sum[i]);
}
- sprintf(&ret[i*2], "-%u", (unsigned)md.totalN);
+ sprintf(&ret[i*2], "-%u", (unsigned)md->totalN);
return ret;
}
}
/* buffer up characters before hashing them */
-static void pushchar(unsigned char c)
+static void pushchar(struct mdfour *hash, unsigned char c)
{
static unsigned char buf[64];
static int len;
if (c == 0) {
if (len > 0) {
- hash_buffer((char *)buf, len);
+ hash_buffer(hash, (char *)buf, len);
len = 0;
}
- hash_buffer(NULL, 0);
+ hash_buffer(hash, NULL, 0);
return;
}
buf[len++] = c;
if (len == 64) {
- hash_buffer((char *)buf, len);
+ hash_buffer(hash, (char *)buf, len);
len = 0;
}
}
/* hash some C/C++ code after unifying */
-static void unify(unsigned char *p, size_t size)
+static void unify(struct mdfour *hash, unsigned char *p, size_t size)
{
size_t ofs;
unsigned char q;
ofs++;
} else {
do {
- pushchar(p[ofs]);
+ pushchar(hash, p[ofs]);
ofs++;
} while (ofs < size && p[ofs] != '\n');
- pushchar('\n');
+ pushchar(hash, '\n');
ofs++;
}
continue;
if (tokens[p[ofs]].type & C_ALPHA) {
do {
- pushchar(p[ofs]);
+ pushchar(hash, p[ofs]);
ofs++;
} while (ofs < size &&
(tokens[p[ofs]].type & (C_ALPHA|C_DIGIT)));
- pushchar('\n');
+ pushchar(hash, '\n');
continue;
}
if (tokens[p[ofs]].type & C_DIGIT) {
do {
- pushchar(p[ofs]);
+ pushchar(hash, p[ofs]);
ofs++;
} while (ofs < size &&
((tokens[p[ofs]].type & C_DIGIT) || p[ofs] == '.'));
if (ofs < size && (p[ofs] == 'x' || p[ofs] == 'X')) {
do {
- pushchar(p[ofs]);
+ pushchar(hash, p[ofs]);
ofs++;
} while (ofs < size && (tokens[p[ofs]].type & C_HEX));
}
if (ofs < size && (p[ofs] == 'E' || p[ofs] == 'e')) {
- pushchar(p[ofs]);
+ pushchar(hash, p[ofs]);
ofs++;
while (ofs < size &&
(tokens[p[ofs]].type & (C_DIGIT|C_SIGN))) {
- pushchar(p[ofs]);
+ pushchar(hash, p[ofs]);
ofs++;
}
}
while (ofs < size && (tokens[p[ofs]].type & C_FLOAT)) {
- pushchar(p[ofs]);
+ pushchar(hash, p[ofs]);
ofs++;
}
- pushchar('\n');
+ pushchar(hash, '\n');
continue;
}
if (tokens[p[ofs]].type & C_QUOTE) {
q = p[ofs];
- pushchar(p[ofs]);
+ pushchar(hash, p[ofs]);
do {
ofs++;
while (ofs < size-1 && p[ofs] == '\\') {
- pushchar(p[ofs]);
- pushchar(p[ofs+1]);
+ pushchar(hash, p[ofs]);
+ pushchar(hash, p[ofs+1]);
ofs+=2;
}
- pushchar(p[ofs]);
+ pushchar(hash, p[ofs]);
} while (ofs < size && p[ofs] != q);
- pushchar('\n');
+ pushchar(hash, '\n');
ofs++;
continue;
}
if (size >= ofs+len && memcmp(&p[ofs], s, len) == 0) {
int j;
for (j=0;s[j];j++) {
- pushchar(s[j]);
+ pushchar(hash, s[j]);
ofs++;
}
- pushchar('\n');
+ pushchar(hash, '\n');
break;
}
}
}
}
- pushchar(p[ofs]);
- pushchar('\n');
+ pushchar(hash, p[ofs]);
+ pushchar(hash, '\n');
ofs++;
}
- pushchar(0);
+ pushchar(hash, 0);
}
/* hash a file that consists of preprocessor output, but remove any line
number information from the hash
*/
-int unify_hash(const char *fname)
+int unify_hash(struct mdfour *hash, const char *fname)
{
int fd;
struct stat st;
close(fd);
/* pass it through the unifier */
- unify((unsigned char *)map, st.st_size);
+ unify(hash, (unsigned char *)map, st.st_size);
munmap(map, st.st_size);