diff options
author | Tharre <tharre3@gmail.com> | 2015-06-13 16:08:54 +0200 |
---|---|---|
committer | Tharre <tharre3@gmail.com> | 2015-06-13 16:08:54 +0200 |
commit | 1e99892519fae2f97a134dc7cc6eeea8d6ade480 (patch) | |
tree | a50a7311754c5beac4822cbf6a98808151ecf2cd /src | |
parent | 43b0098731d2b4a3b0a3191e5eee0ffce7493c30 (diff) | |
download | redo-1e99892519fae2f97a134dc7cc6eeea8d6ade480.tar.gz redo-1e99892519fae2f97a134dc7cc6eeea8d6ade480.tar.xz redo-1e99892519fae2f97a134dc7cc6eeea8d6ade480.zip |
Only hash files once
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/src/build.c b/src/build.c index e57e554..692ed26 100644 --- a/src/build.c +++ b/src/build.c @@ -38,7 +38,8 @@ typedef struct do_attr { typedef struct dep_info { const char *target; char *path; - unsigned char *hash; + unsigned char *old_hash; + unsigned char *new_hash; unsigned int magic; int32_t flags; #define DEP_SOURCE (1 << 1) @@ -67,7 +68,9 @@ static int build_target(dep_info *dep) { /* if our target file has no .do script associated but exists, then we treat it as a source */ dep->flags |= DEP_SOURCE; - dep->hash = hash_file(dep->target); + if (!dep->new_hash) + dep->new_hash = hash_file(dep->target); + write_dep_header(dep); goto exit; } @@ -140,16 +143,11 @@ static int build_target(dep_info *dep) { if (rename(temp_output, dep->target)) fatal("redo: failed to rename %s to %s", temp_output, dep->target); - unsigned char *new_hash = hash_file(dep->target); - if (dep->hash) { - retval = memcmp(new_hash, dep->hash, 20); - if (retval) - memcpy(dep->hash, new_hash, 20); - - free(new_hash); - } else { - dep->hash = new_hash; - } + /* recalculate hash after successful build */ + free(dep->new_hash); + dep->new_hash = hash_file(dep->target); + if (dep->old_hash) + retval = memcmp(dep->new_hash, dep->old_hash, 20); write_dep_header(dep); } else { @@ -162,14 +160,15 @@ static int build_target(dep_info *dep) { .magic = dep->magic, .target = dep->target, .path = get_dep_path(doscripts->chosen), - .hash = NULL, + .old_hash = NULL, + .new_hash = NULL, .flags = 0, }; if (!fexists(dep2.path)) { - dep2.hash = hash_file(doscripts->chosen); + dep2.new_hash = hash_file(doscripts->chosen); write_dep_header(&dep2); - free(dep2.hash); + free(dep2.new_hash); } free(dep2.path); @@ -404,6 +403,13 @@ static void sha1_to_hex(const unsigned char *sha1, char *buf) { } } +static void hex_to_sha1(const char *s, unsigned char *sha1) { + static const char hex[] = "0123456789abcdef"; + + for (; *s; s += 2, ++sha1) + *sha1 = ((strchr(hex, *s) - hex) << 4) + strchr(hex, *(s+1)) - hex; +} + /* Write the dependency information into the specified path. */ static void write_dep_header(dep_info *dep) { mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; @@ -414,7 +420,7 @@ static void write_dep_header(dep_info *dep) { char buf[60]; sprintf(buf, "%010u", dep->magic); buf[10] = '\t'; - sha1_to_hex(dep->hash, buf+11); + sha1_to_hex(dep->new_hash, buf+11); buf[51] = '\t'; memset(buf+52, '-', 7); buf[59] = '\n'; @@ -431,13 +437,15 @@ int update_target(const char *target, int ident) { .magic = atoi(getenv("REDO_MAGIC")), .target = target, .path = get_dep_path(target), - .hash = NULL, + .old_hash = NULL, + .new_hash = NULL, .flags = 0, }; int retval = handle_ident(&dep, ident); free(dep.path); - free(dep.hash); + free(dep.old_hash); + free(dep.new_hash); return retval; } @@ -491,13 +499,12 @@ static int handle_c(dep_info *dep) { /* magic number matches */ return 1; - char char_hash[40]; - - unsigned char *hash = hash_file(dep->target); - sha1_to_hex(hash, char_hash); - free(hash); + dep->old_hash = xmalloc(20); buf[51] = '\0'; - if (memcmp(char_hash, buf+11, 40)) + hex_to_sha1(buf+11, dep->old_hash); /* TODO: error checking */ + dep->new_hash = hash_file(dep->target); + + if (memcmp(dep->old_hash, dep->new_hash, 20)) return build_target(dep); char *ptr; |