aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xprint_dep.py55
-rw-r--r--src/build.c71
2 files changed, 51 insertions, 75 deletions
diff --git a/print_dep.py b/print_dep.py
deleted file mode 100755
index 803b5e9..0000000
--- a/print_dep.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python3
-
-# quick and dirty utility to make the binary mess, produced by my redo program
-# into something more friendly to the human eye
-# requires termcolor (pip install termcolor)
-
-import struct
-import sys
-import hashlib
-from binascii import hexlify
-from os.path import basename
-from termcolor import colored
-
-def convert_back(s):
- return s.replace('!', '/')
-
-if (len(sys.argv) < 2):
- print("Need an argument.")
- exit(1)
-
-hasher = hashlib.sha1()
-file = open(sys.argv[1], 'rb')
-magic = file.read(4)
-hash = file.read(20)
-subdeps = file.read()
-org_file = convert_back(basename(sys.argv[1]))
-
-hash_str = str(hexlify(hash), 'ascii')
-
-with open(org_file, 'rb') as f:
- buf = f.read()
- hasher.update(buf)
-
-print("Target: " + org_file)
-print("Hash: " + hash_str + " ", end="")
-if hasher.hexdigest() == hash_str:
- print(colored(u"\u2714", "green", attrs=['bold']))
-else:
- print(colored(u"\u2718", "red", attrs=['bold']))
-
-print("Magic number: " + str(struct.unpack('i', magic)[0]))
-print("Dependencies:")
-start = True
-thing = ""
-for byte in subdeps:
- if start:
- print(" " + chr(byte) + "-", end="")
- start = False
- elif byte == 0:
- start = True
- print(thing)
- thing = ""
- else:
- thing += chr(byte)
- continue
diff --git a/src/build.c b/src/build.c
index 479b6a0..daef371 100644
--- a/src/build.c
+++ b/src/build.c
@@ -27,8 +27,7 @@
#define _FILENAME "build.c"
#include "dbg.h"
-#define HASHSIZE sizeof(((dep_info*)0)->hash)
-#define HEADERSIZE (sizeof(dep_info)-offsetof(dep_info, magic))
+#define HEADERSIZE 60
typedef struct do_attr {
char *specific;
@@ -88,11 +87,11 @@ int build_target(const char *target) {
if (!fp) {
if (errno != ENOENT)
fatal("redo: failed to open %s\n", dep.path);
- memset(dep.hash, 0, HASHSIZE); // FIXME
+ memset(dep.hash, 0, 20); /* FIXME */
} else {
if (fseek(fp, sizeof(unsigned), SEEK_SET))
fatal("redo: fseek() failed");
- if (fread(dep.hash, 1, HASHSIZE, fp) < HASHSIZE)
+ if (fread(dep.hash, 1, 20, fp) < 20)
fatal("redo: failed to read stuff");
fclose(fp);
}
@@ -159,9 +158,9 @@ int build_target(const char *target) {
unsigned char new_hash[20];
hash_file(target, new_hash);
- retval = memcmp(new_hash, dep.hash, HASHSIZE);
+ retval = memcmp(new_hash, dep.hash, 20);
if (retval)
- memcpy(dep.hash, new_hash, HASHSIZE);
+ memcpy(dep.hash, new_hash, 20);
write_dep_info(&dep);
} else {
@@ -338,6 +337,9 @@ static char *get_dep_path(const char *target) {
void add_dep(const char *target, const char *parent, int ident) {
char *dep_path = get_dep_path(parent);
+ if (strchr(target, '\n'))
+ fatal("Newlines in targets are not supported.");
+
int fd = open(dep_path, O_WRONLY | O_APPEND);
if (fd < 0) {
if (errno != ENOENT)
@@ -351,16 +353,19 @@ void add_dep(const char *target, const char *parent, int ident) {
}
char garbage[HEADERSIZE];
+ memset(garbage, 'Z', HEADERSIZE);
/* skip header */
if (lseek(fd, 0, SEEK_END) < (off_t) HEADERSIZE)
pwrite(fd, garbage, HEADERSIZE, 0);
char *reltarget = get_relpath(target);
- int bufsize = strlen(reltarget) + 2;
+ int bufsize = strlen(reltarget) + 3;
char *buf = xmalloc(bufsize);
buf[0] = ident;
- strcpy(buf+1, reltarget);
+ buf[1] = '\t';
+ strcpy(buf+2, reltarget);
+ buf[bufsize-1] = '\n';
if (write(fd, buf, bufsize) < bufsize)
fatal("redo: failed to write to %s", dep_path);
@@ -392,6 +397,16 @@ static void hash_file(const char *target, unsigned char *hash) {
fclose(in);
}
+void sha1_to_hex(const unsigned char *sha1, char *buf) {
+ static const char hex[] = "0123456789abcdef";
+
+ for (int i = 0; i < 20; ++i) {
+ char *pos = buf + i*2;
+ *pos++ = hex[sha1[i] >> 4];
+ *pos = hex[sha1[i] & 0xf];
+ }
+}
+
/* Write the dependency information into the specified path. */
static void write_dep_info(dep_info *dep) {
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
@@ -399,7 +414,15 @@ static void write_dep_info(dep_info *dep) {
if (out < 0)
fatal("redo: failed to open %s", dep->path);
- if (write(out, &dep->magic, HEADERSIZE) < (ssize_t) HEADERSIZE)
+ char buf[60];
+ sprintf(buf, "%010u", dep->magic);
+ buf[10] = '\t';
+ sha1_to_hex(dep->hash, buf+11);
+ buf[51] = '\t';
+ memset(buf+52, '-', 7);
+ buf[59] = '\n';
+
+ if (write(out, buf, sizeof buf) < (ssize_t) sizeof buf)
fatal("redo: failed to write dependency info to '%s'", dep->path);
if (close(out))
@@ -443,29 +466,36 @@ static int handle_c(const char *target) {
free(dep_path);
- dep_info *dep = (dep_info*) (buf-offsetof(dep_info, magic));
+ errno = 0;
+ buf[10] = '\0';
+ long magic = strtol(buf, NULL, 10);
+ if (errno)
+ return build_target(target);
if (!fexists(target)) {
- if (dep->flags & DEP_SOURCE)
+ if (buf[52] == 'S') /* source flag set */
/* target is a source and must not be rebuild */
return 1;
else
return build_target(target);
}
- if (dep->magic == (unsigned) atoi(getenv("REDO_MAGIC")))
+ if (magic == (unsigned) atoi(getenv("REDO_MAGIC")))
/* magic number matches */
return 1;
+ unsigned char hash[20];
+ char char_hash[40];
- bool rebuild = false;
- unsigned char hash[HASHSIZE];
hash_file(target, hash);
- if (memcmp(hash, dep->hash, HASHSIZE))
+ sha1_to_hex(hash, char_hash);
+ buf[51] = '\0';
+ if (memcmp(char_hash, buf+11, 40))
return build_target(target);
char *ptr;
char *root = getenv("REDO_ROOT");
+ bool rebuild = false;
while (!feof(fp)) {
ptr = buf;
@@ -475,24 +505,25 @@ static int handle_c(const char *target) {
fatal("redo: failed to read %zu bytes from descriptor", sizeof buf);
for (size_t i = 0; i < read; ++i) {
- if (buf[i])
+ if (buf[i] != '\n')
continue;
- if (!is_absolute(&ptr[1])) {
+ buf[i] = '\0';
+ if (!is_absolute(&ptr[2])) {
/* if our path is relative we need to prefix it with the
root project directory or the path will be invalid */
- char *abs = concat(3, root, "/", &ptr[1]);
+ char *abs = concat(3, root, "/", &ptr[2]);
if (update_target(abs, ptr[0]))
rebuild = true;
free(abs);
} else {
- if (update_target(&ptr[1], ptr[0]))
+ if (update_target(&ptr[2], ptr[0]))
rebuild = true;
}
ptr = &buf[i+1];
}
- if (read && buf[read-1]) {
+ if (read && buf[read-1] != '\n') {
if (buf != ptr)
memmove(buf, ptr, buf-ptr + sizeof buf);
else