diff options
| author | Tharre <tharre3@gmail.com> | 2015-01-03 02:22:24 +0100 | 
|---|---|---|
| committer | Tharre <tharre3@gmail.com> | 2015-01-03 03:49:30 +0100 | 
| commit | d56e6f8cf7cab9740fb3ce3d94c859678e6a2b69 (patch) | |
| tree | 97cd26238556acb4990ebbb2384a281d9bd37ca2 /src | |
| parent | 0d6ebe73691b4f4f4039dcaaf468d27b5cc777c6 (diff) | |
| download | redo-d56e6f8cf7cab9740fb3ce3d94c859678e6a2b69.tar.gz redo-d56e6f8cf7cab9740fb3ce3d94c859678e6a2b69.tar.xz redo-d56e6f8cf7cab9740fb3ce3d94c859678e6a2b69.zip | |
Represent dependencies in the dep_info struct
Diffstat (limited to 'src')
| -rw-r--r-- | src/build.c | 127 | 
1 files changed, 64 insertions, 63 deletions
| diff --git a/src/build.c b/src/build.c index 67f99c3..fbfca22 100644 --- a/src/build.c +++ b/src/build.c @@ -27,37 +27,49 @@  #define _FILENAME "build.c"  #include "dbg.h" -#define HASHSIZE 20 -#define HEADERSIZE HASHSIZE + sizeof(unsigned int) +#define HASHSIZE sizeof(((dep_info*)0)->hash) +#define HEADERSIZE (sizeof(dep_info)-offsetof(dep_info, magic)) -static struct do_attr *get_dofiles(const char *target); -static void free_do_attr(struct do_attr *thing); +typedef struct do_attr { +	char *specific; +	char *general; +	char *chosen; +} do_attr; + +typedef struct dep_info { +	char *path; +	unsigned int magic; +	unsigned char hash[20]; +} dep_info; + +static do_attr *get_dofiles(const char *target); +static void free_do_attr(do_attr *thing);  static char **parse_shebang(char *target, char *dofile, char *temp_output);  static char **parsecmd(char *cmd, size_t *i, size_t keep_free);  static char *get_relpath(const char *target);  static char *get_dep_path(const char *target); -static int write_dep_hash(const char *target, unsigned char *old_hash); +static void write_dep_info(dep_info *dep);  static int handle_c(const char *target); - -struct do_attr { -	char *specific; -	char *general; -	char *chosen; -}; +static void hash_file(const char *target, unsigned char *hash);  /* Build given target, using it's do-file. */  int build_target(const char *target) { +	dep_info dep;  	int retval = 1; + +	dep.path = get_dep_path(target); +	dep.magic = atoi(getenv("REDO_MAGIC")); +  	/* get the do-file which we are going to execute */ -	struct do_attr *dofiles = get_dofiles(target); +	do_attr *dofiles = get_dofiles(target);  	if (!dofiles->chosen) {  		if (fexists(target)) {  			/* if our target file has no do file associated but exists,  			   then we treat it as a source */ -			write_dep_hash(target, NULL); -			free_do_attr(dofiles); -			return retval; +			hash_file(target, dep.hash); +			write_dep_info(&dep); +			goto exit;  		}  		die("%s couldn't be built as no suitable do-file exists\n", target); @@ -68,26 +80,23 @@ int build_target(const char *target) {  	free(reltarget);  	/* get the old hash (if any) */ -	unsigned char old_hash[HASHSIZE]; -	char *dep_file = get_dep_path(target); -	FILE *fp = fopen(dep_file, "rb"); +	FILE *fp = fopen(dep.path, "rb");  	if (!fp) {  		if (errno != ENOENT) -			fatal("redo: failed to open %s\n", dep_file); -		memset(old_hash, 0, HASHSIZE); // FIXME +			fatal("redo: failed to open %s\n", dep.path); +		memset(dep.hash, 0, HASHSIZE); // FIXME  	} else {  		if (fseek(fp, sizeof(unsigned), SEEK_SET))  			fatal("redo: fseek() failed"); -		if (fread(old_hash, 1, HASHSIZE, fp) < HASHSIZE) +		if (fread(dep.hash, 1, HASHSIZE, fp) < HASHSIZE)  			fatal("redo: failed to read stuff");  		fclose(fp);  	}  	/* remove old dependency file */ -	if (remove(dep_file)) +	if (remove(dep.path))  		if (errno != ENOENT) -			fatal("redo: failed to remove %s", dep_file); -	free(dep_file); +			fatal("redo: failed to remove %s", dep.path);  	char *temp_output = concat(2, target, ".redoing.tmp"); @@ -132,7 +141,6 @@ int build_target(const char *target) {  	int status;  	if (waitpid(pid, &status, 0) == -1)  		fatal("waitpid() failed: "); -	bool remove_temp = true;  	/* check how our child exited */  	if (WIFEXITED(status)) { @@ -149,19 +157,27 @@ int build_target(const char *target) {  		if (rename(temp_output, target))  			fatal("redo: failed to rename %s to %s", temp_output, target); -		retval = write_dep_hash(target, old_hash); +		unsigned char new_hash[20]; +		hash_file(target, new_hash); +		retval = memcmp(new_hash, dep.hash, HASHSIZE); +		if (retval) +			memcpy(dep.hash, new_hash, HASHSIZE); + +		write_dep_info(&dep);  	} else {  		if (remove(temp_output))  			if (errno != ENOENT)  				fatal("redo: failed to remove %s", temp_output);  	} -	/* depend on the do-file */ -	char *temp = get_dep_path(dofiles->chosen); -	if (!fexists(temp)) -		write_dep_hash(dofiles->chosen, NULL); +	free(dep.path); -	free(temp); +	/* depend on the do-file */ +	dep.path = get_dep_path(dofiles->chosen); +	if (!fexists(dep.path)) { +		hash_file(dofiles->chosen, dep.hash); +		write_dep_info(&dep); +	}  	add_dep(dofiles->chosen, target, 'c');  	/* redo-ifcreate on specific if general was chosen */ @@ -169,6 +185,8 @@ int build_target(const char *target) {  		add_dep(dofiles->specific, target, 'e');  	free(temp_output); +exit: +	free(dep.path);  	free_do_attr(dofiles);  	return retval; @@ -245,8 +263,8 @@ static char **parsecmd(char *cmd, size_t *i, size_t keep_free) {  }  /* Return a struct with all the possible do-files, and the chosen one. */ -static struct do_attr *get_dofiles(const char *target) { -	struct do_attr *dofiles = xmalloc(sizeof(struct do_attr)); +static do_attr *get_dofiles(const char *target) { +	do_attr *dofiles = xmalloc(sizeof(do_attr));  	dofiles->specific = concat(2, target, ".do");  	if (!is_absolute(target)) { @@ -268,8 +286,9 @@ static struct do_attr *get_dofiles(const char *target) {  	return dofiles;  } +  /* Free the do_attr struct. */ -static void free_do_attr(struct do_attr *thing) { +static void free_do_attr(do_attr *thing) {  	free(thing->specific);  	free(thing->general);  	free(thing); @@ -373,36 +392,17 @@ static void hash_file(const char *target, unsigned char *hash) {  	fclose(in);  } -/* Calculate and store the hash of target in the right dependency file. Returns -   a nonzero value if the hash changed or zero otherwise. */ -static int write_dep_hash(const char *target, unsigned char *old_hash) { -	unsigned char hash[HASHSIZE]; -	unsigned magic = atoi(getenv("REDO_MAGIC")); - -	hash_file(target, hash); - -	char *dep_path = get_dep_path(target); - -	int out = open(dep_path, O_WRONLY | O_CREAT, 0644); +/* Write the dependency information into the specified path. */ +static void write_dep_info(dep_info *dep) { +	int out = open(dep->path, O_WRONLY | O_CREAT, 0644);  	if (out < 0) -		fatal("redo: failed to open %s", dep_path); +		fatal("redo: failed to open %s", dep->path); -	if (write(out, &magic, sizeof(unsigned)) < (ssize_t) sizeof(unsigned)) -		fatal("redo: failed to write magic number to '%s'", dep_path); - -	if (write(out, hash, sizeof hash) < (ssize_t) sizeof hash) -		fatal("redo: failed to write hash to '%s'", dep_path); +	if (write(out, &dep->magic, HEADERSIZE) < (ssize_t) HEADERSIZE) +		fatal("redo: failed to write dependency info to '%s'", dep->path);  	if (close(out)) -		fatal("redo: failed to close %s", dep_path); - -	free(dep_path); - -	if (old_hash) -		return memcmp(hash, old_hash, HASHSIZE); -	else -		return 1; - +		fatal("redo: failed to close %s", dep->path);  }  int update_target(const char *target, int ident) { @@ -445,18 +445,19 @@ static int handle_c(const char *target) {  	free(dep_path); -	if (*(unsigned *) buf == (unsigned) atoi(getenv("REDO_MAGIC"))) +	dep_info *dep = (dep_info*) (buf-offsetof(dep_info, magic)); +	if (dep->magic == (unsigned) atoi(getenv("REDO_MAGIC")))  		/* magic number matches */  		return 1; -	char *root = getenv("REDO_ROOT");  	bool rebuild = false;  	unsigned char hash[HASHSIZE];  	hash_file(target, hash); -	if (memcmp(hash, buf+sizeof(unsigned), HASHSIZE)) +	if (memcmp(hash, dep->hash, HASHSIZE))  		return build_target(target);  	char *ptr; +	char *root = getenv("REDO_ROOT");  	while (!feof(fp)) {  		ptr = buf; | 
