aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTharre <tharre3@gmail.com>2014-11-11 14:45:56 +0100
committerTharre <tharre3@gmail.com>2014-11-11 22:06:54 +0100
commit19cba89127381d9dc06d1e823b123231496e9a3d (patch)
tree41512611f8fba3cde9cdb2f098156b4074ea9d17
parent56f3fa373a76842275b199c9ce14fd8e626bd909 (diff)
downloadredo-19cba89127381d9dc06d1e823b123231496e9a3d.tar.gz
redo-19cba89127381d9dc06d1e823b123231496e9a3d.tar.xz
redo-19cba89127381d9dc06d1e823b123231496e9a3d.zip
Fix indentation
-rw-r--r--Redofile26
-rw-r--r--src/build.c730
-rw-r--r--src/dbg.h22
-rw-r--r--src/filepath.c178
-rw-r--r--src/redo-always.c8
-rw-r--r--src/redo-ifchange.c32
-rw-r--r--src/redo-ifcreate.c10
-rw-r--r--src/redo.c58
-rw-r--r--src/util.c72
9 files changed, 568 insertions, 568 deletions
diff --git a/Redofile b/Redofile
index ab241f9..c3eff67 100644
--- a/Redofile
+++ b/Redofile
@@ -8,19 +8,19 @@ export VERSION="pre-0.01"
DESTDIR=${DESTDIR-/usr/bin}
if [ "$1" = "all" ]; then
- redo-ifchange $OUTDIR/redo $OUTDIR/redo-ifchange $OUTDIR/redo-ifcreate \
- $OUTDIR/redo-always
+ redo-ifchange $OUTDIR/redo $OUTDIR/redo-ifchange $OUTDIR/redo-ifcreate \
+ $OUTDIR/redo-always
elif [ "$1" = "clean" ]; then
- rm -rf $OUTDIR/*.tmp $OUTDIR/*.o $OUTDIR/redo $OUTDIR/redo-ifchange \
- $OUTDIR/redo-ifcreate $OUTDIR/redo-always $OUTDIR/CC
- # autoconf stuff
- rm -rf autom4te.cache config.h.in configure config.status config.log config.h
+ rm -rf $OUTDIR/*.tmp $OUTDIR/*.o $OUTDIR/redo $OUTDIR/redo-ifchange \
+ $OUTDIR/redo-ifcreate $OUTDIR/redo-always $OUTDIR/CC
+ # autoconf stuff
+ rm -rf autom4te.cache config.h.in configure config.status config.log config.h
elif [ "$1" = "install" ]; then
- redo-ifchange all
- mkdir -p $DESTDIR
- install $OUTDIR/redo $DESTDIR
- install $OUTDIR/redo-ifchange $DESTDIR
- install $OUTDIR/redo-ifcreate $DESTDIR
- install $OUTDIR/redo-always $DESTDIR
- echo "Finished installing."
+ redo-ifchange all
+ mkdir -p $DESTDIR
+ install $OUTDIR/redo $DESTDIR
+ install $OUTDIR/redo-ifchange $DESTDIR
+ install $OUTDIR/redo-ifcreate $DESTDIR
+ install $OUTDIR/redo-always $DESTDIR
+ echo "Finished installing."
fi
diff --git a/src/build.c b/src/build.c
index 19c06f5..8b0ed94 100644
--- a/src/build.c
+++ b/src/build.c
@@ -39,443 +39,443 @@ static void write_dep_hash(const char *target);
static bool dependencies_changed(char buf[], size_t read);
struct do_attr {
- char *specific;
- char *general;
- char *redofile;
- char *chosen;
+ char *specific;
+ char *general;
+ char *redofile;
+ char *chosen;
};
/* Build given target, using it's do-file. */
int build_target(const char *target) {
- /* get the do-file which we are going to execute */
- struct 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);
- free_do_attr(dofiles);
- return 0;
- }
- log_err("'%s' couldn't be built because no "
- "suitable do-file exists\n", target);
- free_do_attr(dofiles);
- return 1;
- }
-
- char *reltarget = get_relpath(target);
- printf("redo %s\n", reltarget);
- free(reltarget);
-
- /* remove old dependency file */
- char *dep_file = get_dep_path(target);
- if (remove(dep_file))
- if (errno != ENOENT)
- fatal(ERRM_REMOVE, dep_file);
- free(dep_file);
-
- char *temp_output = concat(2, target, ".redoing.tmp");
-
- pid_t pid = fork();
- if (pid == -1) {
- /* failure */
- fatal(ERRM_FORK);
- } else if (pid == 0) {
- /* child */
-
- /* change directory to our target */
- char *dirc = safe_strdup(target);
- char *dtarget = dirname(dirc);
- if (chdir(dtarget) == -1)
- fatal(ERRM_CHDIR, dtarget);
-
- free(dirc);
-
- /* target is now in the cwd so change path accordingly */
- char *btarget = xbasename(target);
- char *bdo_file = xbasename(dofiles->chosen);
- char *btemp_output = xbasename(temp_output);
-
- char **argv = parse_shebang(btarget, bdo_file, btemp_output);
-
- /* set "REDO_PARENT_TARGET" */
- if (setenv("REDO_PARENT_TARGET", target, 1))
- fatal(ERRM_SETENV, "REDO_PARENT_TARGET", target);
-
- /* excelp() has nearly everything we want: automatic parsing of the
- shebang line through execve() and fallback to /bin/sh if no valid
- shebang could be found. However, it fails if the target doesn't have
- the executeable bit set, which is something we don't want. For this
- reason we parse the shebang line ourselves. */
- execv(argv[0], argv);
-
- /* execv should never return */
- fatal(ERRM_EXEC, argv[0]);
- }
-
- /* parent */
- int status;
- if (waitpid(pid, &status, 0) == -1)
- fatal("waitpid() failed: ");
- bool remove_temp = true;
-
- if (WIFEXITED(status)) {
- if (WEXITSTATUS(status)) {
- log_err("redo: invoked do-file %s failed: %d\n",
- dofiles->chosen, WEXITSTATUS(status));
- exit(EXIT_FAILURE);
- } else {
- /* successful */
-
- /* if the file is 0 bytes long we delete it */
- if (fsize(temp_output) > 0)
- remove_temp = false;
- }
- } else {
- /* something very wrong happened with the child */
- log_err("redo: invoked do-file did not terminate correctly\n");
- exit(EXIT_FAILURE);
- }
-
- /* depend on the do-file */
- add_dep(dofiles->chosen, target, 'c');
- write_dep_hash(dofiles->chosen);
-
- /* redo-ifcreate on specific if general was chosen */
- if (dofiles->general == dofiles->chosen)
- add_dep(dofiles->specific, target, 'e');
-
- if (remove_temp) {
- if (remove(temp_output))
- if (errno != ENOENT)
- fatal(ERRM_REMOVE, temp_output);
- } else {
- if (rename(temp_output, target))
- fatal(ERRM_RENAME, temp_output, target);
-
- write_dep_hash(target);
- }
-
- free(temp_output);
- free_do_attr(dofiles);
-
- return 0;
+ /* get the do-file which we are going to execute */
+ struct 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);
+ free_do_attr(dofiles);
+ return 0;
+ }
+ log_err("'%s' couldn't be built because no "
+ "suitable do-file exists\n", target);
+ free_do_attr(dofiles);
+ return 1;
+ }
+
+ char *reltarget = get_relpath(target);
+ printf("redo %s\n", reltarget);
+ free(reltarget);
+
+ /* remove old dependency file */
+ char *dep_file = get_dep_path(target);
+ if (remove(dep_file))
+ if (errno != ENOENT)
+ fatal(ERRM_REMOVE, dep_file);
+ free(dep_file);
+
+ char *temp_output = concat(2, target, ".redoing.tmp");
+
+ pid_t pid = fork();
+ if (pid == -1) {
+ /* failure */
+ fatal(ERRM_FORK);
+ } else if (pid == 0) {
+ /* child */
+
+ /* change directory to our target */
+ char *dirc = safe_strdup(target);
+ char *dtarget = dirname(dirc);
+ if (chdir(dtarget) == -1)
+ fatal(ERRM_CHDIR, dtarget);
+
+ free(dirc);
+
+ /* target is now in the cwd so change path accordingly */
+ char *btarget = xbasename(target);
+ char *bdo_file = xbasename(dofiles->chosen);
+ char *btemp_output = xbasename(temp_output);
+
+ char **argv = parse_shebang(btarget, bdo_file, btemp_output);
+
+ /* set "REDO_PARENT_TARGET" */
+ if (setenv("REDO_PARENT_TARGET", target, 1))
+ fatal(ERRM_SETENV, "REDO_PARENT_TARGET", target);
+
+ /* excelp() has nearly everything we want: automatic parsing of the
+ shebang line through execve() and fallback to /bin/sh if no valid
+ shebang could be found. However, it fails if the target doesn't have
+ the executeable bit set, which is something we don't want. For this
+ reason we parse the shebang line ourselves. */
+ execv(argv[0], argv);
+
+ /* execv should never return */
+ fatal(ERRM_EXEC, argv[0]);
+ }
+
+ /* parent */
+ int status;
+ if (waitpid(pid, &status, 0) == -1)
+ fatal("waitpid() failed: ");
+ bool remove_temp = true;
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status)) {
+ log_err("redo: invoked do-file %s failed: %d\n",
+ dofiles->chosen, WEXITSTATUS(status));
+ exit(EXIT_FAILURE);
+ } else {
+ /* successful */
+
+ /* if the file is 0 bytes long we delete it */
+ if (fsize(temp_output) > 0)
+ remove_temp = false;
+ }
+ } else {
+ /* something very wrong happened with the child */
+ log_err("redo: invoked do-file did not terminate correctly\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* depend on the do-file */
+ add_dep(dofiles->chosen, target, 'c');
+ write_dep_hash(dofiles->chosen);
+
+ /* redo-ifcreate on specific if general was chosen */
+ if (dofiles->general == dofiles->chosen)
+ add_dep(dofiles->specific, target, 'e');
+
+ if (remove_temp) {
+ if (remove(temp_output))
+ if (errno != ENOENT)
+ fatal(ERRM_REMOVE, temp_output);
+ } else {
+ if (rename(temp_output, target))
+ fatal(ERRM_RENAME, temp_output, target);
+
+ write_dep_hash(target);
+ }
+
+ free(temp_output);
+ free_do_attr(dofiles);
+
+ return 0;
}
/* Read and parse shebang and return an argv-like pointer array containing the
arguments. If no valid shebang could be found, assume "/bin/sh -e" instead. */
static char **parse_shebang(char *target, char *dofile, char *temp_output) {
- FILE *fp = fopen(dofile, "rb");
- if (!fp)
- fatal(ERRM_FOPEN, dofile);
-
- char buf[1024];
-
- buf[ fread(buf, 1, sizeof(buf)-1, fp) ] = '\0';
- if (ferror(fp))
- fatal(ERRM_FREAD, dofile);
-
- fclose(fp);
-
- char **argv;
- size_t i = 0;
- if (buf[0] == '#' && buf[1] == '!') {
- argv = parsecmd(&buf[2], &i, 5);
- } else {
- argv = safe_malloc(7 * sizeof(char*));
- argv[i++] = "/bin/sh";
- argv[i++] = "-e";
- }
-
- argv[i++] = dofile;
- argv[i++] = (char*) target;
- char *basename = remove_ext(target);
- argv[i++] = basename;
- argv[i++] = temp_output;
- argv[i] = NULL;
-
- return argv;
+ FILE *fp = fopen(dofile, "rb");
+ if (!fp)
+ fatal(ERRM_FOPEN, dofile);
+
+ char buf[1024];
+
+ buf[ fread(buf, 1, sizeof(buf)-1, fp) ] = '\0';
+ if (ferror(fp))
+ fatal(ERRM_FREAD, dofile);
+
+ fclose(fp);
+
+ char **argv;
+ size_t i = 0;
+ if (buf[0] == '#' && buf[1] == '!') {
+ argv = parsecmd(&buf[2], &i, 5);
+ } else {
+ argv = safe_malloc(7 * sizeof(char*));
+ argv[i++] = "/bin/sh";
+ argv[i++] = "-e";
+ }
+
+ argv[i++] = dofile;
+ argv[i++] = (char*) target;
+ char *basename = remove_ext(target);
+ argv[i++] = basename;
+ argv[i++] = temp_output;
+ argv[i] = NULL;
+
+ return argv;
}
/* 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 = safe_malloc(sizeof(struct do_attr));
-
- dofiles->specific = concat(2, target, ".do");
- dofiles->general = concat(3, "default", take_extension(target), ".do");
- dofiles->redofile = safe_strdup("Redofile");
-
- if (fexists(dofiles->specific))
- dofiles->chosen = dofiles->specific;
- else if (fexists(dofiles->general))
- dofiles->chosen = dofiles->general;
- else if (fexists(dofiles->redofile))
- dofiles->chosen = dofiles->redofile;
- else
- dofiles->chosen = NULL;
-
- return dofiles;
+ struct do_attr *dofiles = safe_malloc(sizeof(struct do_attr));
+
+ dofiles->specific = concat(2, target, ".do");
+ dofiles->general = concat(3, "default", take_extension(target), ".do");
+ dofiles->redofile = safe_strdup("Redofile");
+
+ if (fexists(dofiles->specific))
+ dofiles->chosen = dofiles->specific;
+ else if (fexists(dofiles->general))
+ dofiles->chosen = dofiles->general;
+ else if (fexists(dofiles->redofile))
+ dofiles->chosen = dofiles->redofile;
+ else
+ dofiles->chosen = NULL;
+
+ return dofiles;
}
/* Free the do_attr struct. */
static void free_do_attr(struct do_attr *thing) {
- assert(thing);
- free(thing->specific);
- free(thing->general);
- free(thing->redofile);
- free(thing);
+ assert(thing);
+ free(thing->specific);
+ free(thing->general);
+ free(thing->redofile);
+ free(thing);
}
/* Breaks cmd at spaces and stores a pointer to each argument in the returned
array. The index i is incremented to point to the next free pointer. The
returned array is guaranteed to have at least keep_free entries left. */
static char **parsecmd(char *cmd, size_t *i, size_t keep_free) {
- size_t argv_len = 16;
- char **argv = safe_malloc(argv_len * sizeof(char*));
- size_t j = 0;
- bool prev_space = true;
- for (;; ++j) {
- switch (cmd[j]) {
- case ' ':
- cmd[j] = '\0';
- prev_space = true;
- break;
- case '\n':
- case '\r':
- cmd[j] = '\0';
- case '\0':
- return argv;
- default:
- if (!prev_space)
- break;
- /* check if we have enough space */
- while (*i+keep_free >= argv_len) {
- argv_len *= 2;
- debug("Reallocating memory (now %zu elements)\n", argv_len);
- argv = safe_realloc(argv, argv_len * sizeof(char*));
- }
-
- prev_space = false;
- argv[*i] = &cmd[j];
- ++*i;
- }
- }
+ size_t argv_len = 16;
+ char **argv = safe_malloc(argv_len * sizeof(char*));
+ size_t j = 0;
+ bool prev_space = true;
+ for (;; ++j) {
+ switch (cmd[j]) {
+ case ' ':
+ cmd[j] = '\0';
+ prev_space = true;
+ break;
+ case '\n':
+ case '\r':
+ cmd[j] = '\0';
+ case '\0':
+ return argv;
+ default:
+ if (!prev_space)
+ break;
+ /* check if we have enough space */
+ while (*i+keep_free >= argv_len) {
+ argv_len *= 2;
+ debug("Reallocating memory (now %zu elements)\n", argv_len);
+ argv = safe_realloc(argv, argv_len * sizeof(char*));
+ }
+
+ prev_space = false;
+ argv[*i] = &cmd[j];
+ ++*i;
+ }
+ }
}
/* Custom version of realpath that doesn't fail if the last part of path
doesn't exist and allocates memory for the result itself. */
static char *xrealpath(const char *path) {
- char *dirc = safe_strdup(path);
- char *dname = dirname(dirc);
- char *absdir = realpath(dname, NULL);
- if (!absdir)
- return NULL;
- char *abstarget = concat(3, absdir, "/", xbasename(path));
-
- free(dirc);
- free(absdir);
- return abstarget;
+ char *dirc = safe_strdup(path);
+ char *dname = dirname(dirc);
+ char *absdir = realpath(dname, NULL);
+ if (!absdir)
+ return NULL;
+ char *abstarget = concat(3, absdir, "/", xbasename(path));
+
+ free(dirc);
+ free(absdir);
+ return abstarget;
}
/* Return the relative path against "REDO_ROOT" of target. */
static char *get_relpath(const char *target) {
- assert(getenv("REDO_ROOT"));
+ assert(getenv("REDO_ROOT"));
- char *root = getenv("REDO_ROOT");
- char *abstarget = xrealpath(target);
+ char *root = getenv("REDO_ROOT");
+ char *abstarget = xrealpath(target);
- if (!abstarget)
- fatal(ERRM_REALPATH, target);
+ if (!abstarget)
+ fatal(ERRM_REALPATH, target);
- char *relpath = safe_strdup(make_relative(root, abstarget));
- free(abstarget);
- return relpath;
+ char *relpath = safe_strdup(make_relative(root, abstarget));
+ free(abstarget);
+ return relpath;
}
/* Return the dependency file path of target. */
static char *get_dep_path(const char *target) {
- assert(getenv("REDO_ROOT"));
+ assert(getenv("REDO_ROOT"));
- char *root = getenv("REDO_ROOT");
- char *reltarget = get_relpath(target);
- char *safe_target = transform_path(reltarget);
- char *dep_path = concat(3, root, "/.redo/deps/", safe_target);
+ char *root = getenv("REDO_ROOT");
+ char *reltarget = get_relpath(target);
+ char *safe_target = transform_path(reltarget);
+ char *dep_path = concat(3, root, "/.redo/deps/", safe_target);
- free(reltarget);
- free(safe_target);
- return dep_path;
+ free(reltarget);
+ free(safe_target);
+ return dep_path;
}
/* Add the dependency target, with the identifier ident. If parent is NULL, the
* value of the environment variable REDO_PARENT will be taken instead. */
void add_dep(const char *target, const char *parent, int ident) {
- if (!parent) {
- assert(getenv("REDO_PARENT_TARGET"));
- parent = getenv("REDO_PARENT_TARGET");
- }
-
- char *dep_path = get_dep_path(parent);
-
- FILE *fp = fopen(dep_path, "rb+");
- if (!fp) {
- if (errno == ENOENT) {
- fp = fopen(dep_path, "w");
- if (!fp)
- fatal(ERRM_FOPEN, dep_path);
- /* skip the first n bytes that are reserved for the hash + magic number */
- fseek(fp, HASHSIZE + sizeof(unsigned int), SEEK_SET);
- } else {
- fatal(ERRM_FOPEN, dep_path);
- }
- } else {
- fseek(fp, 0L, SEEK_END);
- }
-
- char *reltarget = get_relpath(target);
-
- putc(ident, fp);
- fputs(reltarget, fp);
- putc('\0', fp);
-
- if (ferror(fp))
- fatal(ERRM_WRITE, dep_path);
-
- if (fclose(fp))
- fatal(ERRM_FCLOSE, dep_path);
- free(dep_path);
- free(reltarget);
+ if (!parent) {
+ assert(getenv("REDO_PARENT_TARGET"));
+ parent = getenv("REDO_PARENT_TARGET");
+ }
+
+ char *dep_path = get_dep_path(parent);
+
+ FILE *fp = fopen(dep_path, "rb+");
+ if (!fp) {
+ if (errno == ENOENT) {
+ fp = fopen(dep_path, "w");
+ if (!fp)
+ fatal(ERRM_FOPEN, dep_path);
+ /* skip the first n bytes that are reserved for the hash + magic number */
+ fseek(fp, HASHSIZE + sizeof(unsigned int), SEEK_SET);
+ } else {
+ fatal(ERRM_FOPEN, dep_path);
+ }
+ } else {
+ fseek(fp, 0L, SEEK_END);
+ }
+
+ char *reltarget = get_relpath(target);
+
+ putc(ident, fp);
+ fputs(reltarget, fp);
+ putc('\0', fp);
+
+ if (ferror(fp))
+ fatal(ERRM_WRITE, dep_path);
+
+ if (fclose(fp))
+ fatal(ERRM_FCLOSE, dep_path);
+ free(dep_path);
+ free(reltarget);
}
/* Hash target, storing the result in hash. */
static void hash_file(const char *target, unsigned char *hash) {
- FILE *in = fopen(target, "rb");
- if (!in)
- fatal(ERRM_FOPEN, target);
-
- SHA_CTX context;
- unsigned char data[8192];
- size_t read;
-
- SHA1_Init(&context);
- while ((read = fread(data, 1, sizeof data, in)))
- SHA1_Update(&context, data, read);
-
- if (ferror(in))
- fatal(ERRM_FREAD, target);
- SHA1_Final(hash, &context);
- fclose(in);
+ FILE *in = fopen(target, "rb");
+ if (!in)
+ fatal(ERRM_FOPEN, target);
+
+ SHA_CTX context;
+ unsigned char data[8192];
+ size_t read;
+
+ SHA1_Init(&context);
+ while ((read = fread(data, 1, sizeof data, in)))
+ SHA1_Update(&context, data, read);
+
+ if (ferror(in))
+ fatal(ERRM_FREAD, target);
+ SHA1_Final(hash, &context);
+ fclose(in);
}
/* Calculate and store the hash of target in the right dependency file. */
static void write_dep_hash(const char *target) {
- assert(getenv("REDO_MAGIC"));
+ assert(getenv("REDO_MAGIC"));
- unsigned char hash[HASHSIZE];
- unsigned magic = atoi(getenv("REDO_MAGIC"));
+ unsigned char hash[HASHSIZE];
+ unsigned magic = atoi(getenv("REDO_MAGIC"));
- hash_file(target, hash);
+ hash_file(target, hash);
- char *dep_path = get_dep_path(target);
- int out = open(dep_path, O_WRONLY | O_CREAT, 0644);
- if (out < 0)
- fatal(ERRM_FOPEN, dep_path);
+ char *dep_path = get_dep_path(target);
+ int out = open(dep_path, O_WRONLY | O_CREAT, 0644);
+ if (out < 0)
+ fatal(ERRM_FOPEN, 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, &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, hash, sizeof hash) < (ssize_t) sizeof hash)
+ fatal("redo: failed to write hash to '%s'", dep_path);
- if (close(out))
- fatal(ERRM_FCLOSE, dep_path);
- free(dep_path);
+ if (close(out))
+ fatal(ERRM_FCLOSE, dep_path);
+ free(dep_path);
}
/* Parse the dependency information from the dependency record and check if
those are up-to-date. */
static bool dependencies_changed(char buf[], size_t read) {
- char *root = getenv("REDO_ROOT");
- char *ptr = buf;
-
- for (size_t i = 0; i < read; ++i) {
- if (buf[i])
- continue;
- if (is_absolute(&ptr[1])) {
- if (has_changed(&ptr[1], ptr[0], true))
- return true;
- } else {
- char *abs = concat(3, root, "/", &ptr[1]);
- if (has_changed(abs, ptr[0], true)) {
- free(abs);
- return true;
- }
- free(abs);
- }
- ptr = &buf[i+1];
- }
- return false;
+ char *root = getenv("REDO_ROOT");
+ char *ptr = buf;
+
+ for (size_t i = 0; i < read; ++i) {
+ if (buf[i])
+ continue;
+ if (is_absolute(&ptr[1])) {
+ if (has_changed(&ptr[1], ptr[0], true))
+ return true;
+ } else {
+ char *abs = concat(3, root, "/", &ptr[1]);
+ if (has_changed(abs, ptr[0], true)) {
+ free(abs);
+ return true;
+ }
+ free(abs);
+ }
+ ptr = &buf[i+1];
+ }
+ return false;
}
/* Checks if a target should be rebuild, given it's identifier. */
bool has_changed(const char *target, int ident, bool is_sub_dependency) {
- switch(ident) {
- case 'a': return true;
- case 'e': return fexists(target);
- case 'c':
+ switch(ident) {
+ case 'a': return true;
+ case 'e': return fexists(target);
+ case 'c':
#define HEADERSIZE HASHSIZE + sizeof(unsigned)
- if (!fexists(target))
- return true;
-
- char *dep_path = get_dep_path(target);
-
- FILE *fp = fopen(dep_path, "rb");
- if (!fp) {
- if (errno == ENOENT) {
- /* dependency file does not exist */
- return true;
- } else {
- fatal(ERRM_FOPEN, dep_path);
- }
- }
-
- char buf[8096];
- if (fread(buf, 1, HEADERSIZE, fp) < HEADERSIZE)
- fatal("redo: failed to read %zu bytes from %s", HEADERSIZE, dep_path);
-
- free(dep_path);
-
- if (*(unsigned *) buf == (unsigned) atoi(getenv("REDO_MAGIC")))
- return is_sub_dependency;
-
- unsigned char hash[HASHSIZE];
- hash_file(target, hash);
- if (memcmp(hash, buf+sizeof(unsigned), HASHSIZE)) {
- /*debug("Hash doesn't match for %s\n", target);*/
- return true;
- }
-
- while (!feof(fp)) {
- size_t read = fread(buf, 1, sizeof buf, fp);
-
- if (ferror(fp))
- fatal("redo: failed to read %zu bytes from file descriptor", sizeof buf);
-
- if (dependencies_changed(buf, read)) {
- fclose(fp);
- return true;
- }
- }
-
- fclose(fp);
- return false;
-
- default:
- log_err("Unknown identifier '%c'\n", ident);
- exit(EXIT_FAILURE);
- }
+ if (!fexists(target))
+ return true;
+
+ char *dep_path = get_dep_path(target);
+
+ FILE *fp = fopen(dep_path, "rb");
+ if (!fp) {
+ if (errno == ENOENT) {
+ /* dependency file does not exist */
+ return true;
+ } else {
+ fatal(ERRM_FOPEN, dep_path);
+ }
+ }
+
+ char buf[8096];
+ if (fread(buf, 1, HEADERSIZE, fp) < HEADERSIZE)
+ fatal("redo: failed to read %zu bytes from %s", HEADERSIZE, dep_path);
+
+ free(dep_path);
+
+ if (*(unsigned *) buf == (unsigned) atoi(getenv("REDO_MAGIC")))
+ return is_sub_dependency;
+
+ unsigned char hash[HASHSIZE];
+ hash_file(target, hash);
+ if (memcmp(hash, buf+sizeof(unsigned), HASHSIZE)) {
+ /*debug("Hash doesn't match for %s\n", target);*/
+ return true;
+ }
+
+ while (!feof(fp)) {
+ size_t read = fread(buf, 1, sizeof buf, fp);
+
+ if (ferror(fp))
+ fatal("redo: failed to read %zu bytes from file descriptor", sizeof buf);
+
+ if (dependencies_changed(buf, read)) {
+ fclose(fp);
+ return true;
+ }
+ }
+
+ fclose(fp);
+ return false;
+
+ default:
+ log_err("Unknown identifier '%c'\n", ident);
+ exit(EXIT_FAILURE);
+ }
}
bool environment_sane() {
- return getenv("REDO_ROOT") && getenv("REDO_PARENT_TARGET") && getenv("REDO_MAGIC");
+ return getenv("REDO_ROOT") && getenv("REDO_PARENT_TARGET") && getenv("REDO_MAGIC");
}
diff --git a/src/dbg.h b/src/dbg.h
index afbb21f..28a6fae 100644
--- a/src/dbg.h
+++ b/src/dbg.h
@@ -24,7 +24,7 @@
#define LOG_HELPER(f,l,...) fprintf(stderr, "("f":"STRINGIFY(l)"): "__VA_ARGS__)
#define FATAL_HELPER(M, ...) log_err(M ": %s\n", __VA_ARGS__)
#define FATAL_HELPER_(f,l,M,...) \
- fprintf(stderr, "(%s:%u): " M ": %s\n", f, l, __VA_ARGS__)
+ fprintf(stderr, "(%s:%u): " M ": %s\n", f, l, __VA_ARGS__)
#ifdef NDEBUG
#define debug(...)
@@ -34,22 +34,22 @@
#define log_err(...) LOG_HELPER(_FILENAME, __LINE__, __VA_ARGS__)
#define fatal(...) \
- ({FATAL_HELPER(__VA_ARGS__, strerror(errno)); exit(EXIT_FAILURE);})
+ ({FATAL_HELPER(__VA_ARGS__, strerror(errno)); exit(EXIT_FAILURE);})
#define fatal_(f,l,...) \
- ({FATAL_HELPER_(f, l, __VA_ARGS__, strerror(errno)); exit(EXIT_FAILURE);})
+ ({FATAL_HELPER_(f, l, __VA_ARGS__, strerror(errno)); exit(EXIT_FAILURE);})
#define assert_str_equal(a,b) ({ \
- if (strcmp(a, b)) { \
- log_err("Assertion error: '%s' == '%s'\n", a, b); \
- abort(); \
- } \
+ if (strcmp(a, b)) { \
+ log_err("Assertion error: '%s' == '%s'\n", a, b); \
+ abort(); \
+ } \
})
#define assert_int_equal(a,b) ({ \
- if (a != b) { \
- log_err("Assertion error: '%d' == '%d'\n", a, b); \
- abort(); \
- } \
+ if (a != b) { \
+ log_err("Assertion error: '%d' == '%d'\n", a, b); \
+ abort(); \
+ } \
})
/* A neat macro that silences unused parameter warnings compiler independant */
diff --git a/src/filepath.c b/src/filepath.c
index ff1b476..7d73b60 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -19,135 +19,135 @@
/* Check if the given path is absolute. */
bool is_absolute(const char* path) {
- return path[0] == '/';
+ return path[0] == '/';
}
/* Returns a new copy of str with the extension removed, where the extension is
everything behind the last dot, including the dot. */
char *remove_ext(const char *str) {
- assert(str);
- size_t len;
- char *ret, *dot = NULL;
+ assert(str);
+ size_t len;
+ char *ret, *dot = NULL;
- for (len = 0; str[len]; ++len)
- if (str[len] == '.')
- dot = (char*) &str[len];
+ for (len = 0; str[len]; ++len)
+ if (str[len] == '.')
+ dot = (char*) &str[len];
- if (dot) /* recalculate length to only reach just before the last dot */
- len = dot - str;
+ if (dot) /* recalculate length to only reach just before the last dot */
+ len = dot - str;
- ret = safe_malloc(len+1);
- memcpy(ret, str, len);
- ret[len] = '\0';
+ ret = safe_malloc(len+1);
+ memcpy(ret, str, len);
+ ret[len] = '\0';
- return ret;
+ return ret;
}
/* Returns the extension of the target or the empty string if none was found. */
char *take_extension(const char *target) {
- assert(target);
- char *temp = strrchr(target, '.');
- if (temp)
- return temp;
- else
- return "";
+ assert(target);
+ char *temp = strrchr(target, '.');
+ if (temp)
+ return temp;
+ else
+ return "";
}
/* Make one path relative to another i.e. some/path to some/path/a/b/c would
yield a/b/c as result. Prints '.' if the 2 paths match. */
// TODO: nameing, requires absolute paths, doesn't MALLOC
const char *make_relative(const char *target, const char *to) {
- int i;
- for (i = 0; target[i] && to[i]; ++i)
- if (target[i] != to[i]) {
- /* the paths do not match */
- return to;
- }
-
- if (!target[i] && !to[i]) {
- /* both paths match completely */
- return ".";
- }
-
- /* skip any leading seperators */
- while (to[i] == '/')
- ++i;
-
- return &to[i];
+ int i;
+ for (i = 0; target[i] && to[i]; ++i)
+ if (target[i] != to[i]) {
+ /* the paths do not match */
+ return to;
+ }
+
+ if (!target[i] && !to[i]) {
+ /* both paths match completely */
+ return ".";
+ }
+
+ /* skip any leading seperators */
+ while (to[i] == '/')
+ ++i;
+
+ return &to[i];
}
/* Transforms target into a safe filename, replacing all '/' with '!'. */
char *transform_path(const char *target) {
- char *ptr = (char*) target;
- size_t escape = 0, i = 0;
- while (*ptr++)
- if (*ptr == '!') escape++;
-
- ptr = safe_malloc((ptr-target) + escape + 1);
- do {
- if (*target == '/')
- ptr[i++] = '!';
- else if (*target == '!') {
- ptr[i++] = '!';
- ptr[i++] = '!';
- } else
- ptr[i++] = *target;
- } while (*target++);
-
- ptr[i] = '\0';
- return ptr;
+ char *ptr = (char*) target;
+ size_t escape = 0, i = 0;
+ while (*ptr++)
+ if (*ptr == '!') escape++;
+
+ ptr = safe_malloc((ptr-target) + escape + 1);
+ do {
+ if (*target == '/')
+ ptr[i++] = '!';
+ else if (*target == '!') {
+ ptr[i++] = '!';
+ ptr[i++] = '!';
+ } else
+ ptr[i++] = *target;
+ } while (*target++);
+
+ ptr[i] = '\0';
+ return ptr;
}
/* Sane and portable basename implementation. */
char *xbasename(const char *path) {
- assert(path);
- char *ptr = strrchr(path, '/');
- return ptr? ptr+1 : (char*) path;
+ assert(path);
+ char *ptr = strrchr(path, '/');
+ return ptr? ptr+1 : (char*) path;
}
/* Checks if target exists and prints a debug message if access() failed
except if it failed with ENOENT. */
bool fexists(const char *target) {
- assert(target);
- if (!access(target, F_OK))
- return true;
- if (errno != ENOENT)
- debug("Failed to access %s: %s\n", target, strerror(errno));
- return false;
+ assert(target);
+ if (!access(target, F_OK))
+ return true;
+ if (errno != ENOENT)
+ debug("Failed to access %s: %s\n", target, strerror(errno));
+ return false;
}
/* Returns the size of fn, or -1 if the file doesn't exist. */
off_t fsize(const char *fn) {
- struct stat st;
- if (stat(fn, &st)) {
- if (errno != ENOENT)
- fatal(ERRM_STAT, fn);
- return -1;
- }
-
- return st.st_size;
+ struct stat st;
+ if (stat(fn, &st)) {
+ if (errno != ENOENT)
+ fatal(ERRM_STAT, fn);
+ return -1;
+ }
+
+ return st.st_size;
}
/* Create the directory dir, while removing other 'files' with the same name.
Returns true if the directory had to be created or false if it existed */
// TODO: fix confusing name
bool mkdirp(const char *dir) {
- struct stat st;
- if (stat(dir, &st)) {
- /* dir doesn't exist or stat failed */
- if (errno != ENOENT)
- fatal(ERRM_STAT, dir);
- if (mkdir(dir, 0755))
- fatal(ERRM_MKDIR, dir);
- return 1;
- } else {
- if (!S_ISDIR(st.st_mode)) {
- if (remove(dir))
- fatal(ERRM_REMOVE, dir);
- if (mkdir(dir, 0755))
- fatal(ERRM_MKDIR, dir);
- return 1;
- }
- return 0;
- }
+ struct stat st;
+ if (stat(dir, &st)) {
+ /* dir doesn't exist or stat failed */
+ if (errno != ENOENT)
+ fatal(ERRM_STAT, dir);
+ if (mkdir(dir, 0755))
+ fatal(ERRM_MKDIR, dir);
+ return 1;
+ } else {
+ if (!S_ISDIR(st.st_mode)) {
+ if (remove(dir))
+ fatal(ERRM_REMOVE, dir);
+ if (mkdir(dir, 0755))
+ fatal(ERRM_MKDIR, dir);
+ return 1;
+ }
+ return 0;
+ }
}
diff --git a/src/redo-always.c b/src/redo-always.c
index 352e6c8..5f0c24c 100644
--- a/src/redo-always.c
+++ b/src/redo-always.c
@@ -11,8 +11,8 @@
#include "build.h"
int main(int argc, char *argv[]) {
- for (int i = 1; i < argc; ++i) {
- build_target(argv[i]);
- add_dep(argv[i], NULL, 'a');
- }
+ for (int i = 1; i < argc; ++i) {
+ build_target(argv[i]);
+ add_dep(argv[i], NULL, 'a');
+ }
}
diff --git a/src/redo-ifchange.c b/src/redo-ifchange.c
index 75bd984..cfc017b 100644
--- a/src/redo-ifchange.c
+++ b/src/redo-ifchange.c
@@ -13,22 +13,22 @@
#include "dbg.h"
int main(int argc, char *argv[]) {
- if (!environment_sane()) {
- fprintf(stderr, "redo: environment variables are missing, \
- please use %s only in do scripts.\n", argv[0]);
- exit(1);
- }
+ if (!environment_sane()) {
+ fprintf(stderr, "redo: environment variables are missing, \
+ please use %s only in do scripts.\n", argv[0]);
+ exit(1);
+ }
- for (int i = 1; i < argc; ++i) {
- /*debug("Testing if %s is up-to-date ...\n", argv[i]);*/
- if (has_changed(argv[i], 'c', false)) {
- /*printf("=> no\n");*/
- build_target(argv[i]);
- } else {
- /*printf("=> yes\n");*/
- }
- add_dep(argv[i], NULL, 'c');
- }
+ for (int i = 1; i < argc; ++i) {
+ /*debug("Testing if %s is up-to-date ...\n", argv[i]);*/
+ if (has_changed(argv[i], 'c', false)) {
+ /*printf("=> no\n");*/
+ build_target(argv[i]);
+ } else {
+ /*printf("=> yes\n");*/
+ }
+ add_dep(argv[i], NULL, 'c');
+ }
- return 0;
+ return 0;
}
diff --git a/src/redo-ifcreate.c b/src/redo-ifcreate.c
index 955ffdc..eba1c6b 100644
--- a/src/redo-ifcreate.c
+++ b/src/redo-ifcreate.c
@@ -11,9 +11,9 @@
#include "build.h"
int main(int argc, char *argv[]) {
- for (int i = 1; i < argc; ++i) {
- if (has_changed(argv[i], 'e', false))
- build_target(argv[i]);
- add_dep(argv[i], NULL, 'e');
- }
+ for (int i = 1; i < argc; ++i) {
+ if (has_changed(argv[i], 'e', false))
+ build_target(argv[i]);
+ add_dep(argv[i], NULL, 'e');
+ }
}
diff --git a/src/redo.c b/src/redo.c
index a178edb..1458391 100644
--- a/src/redo.c
+++ b/src/redo.c
@@ -23,39 +23,39 @@
/* Returns the amount of digits a number n has in decimal. */
static inline unsigned digits(unsigned n) {
- return n ? 1 + digits(n/10) : n;
+ return n ? 1 + digits(n/10) : n;
}
void prepare_env() {
- /* create the dependency store if it doesn't already exist */
- if (mkdirp(".redo") && mkdirp(".redo/deps"))
- fprintf(stderr, "redo: creating dependency store ...\n");
-
- /* set REDO_ROOT */
- char *cwd = getcwd(NULL, 0);
- if (!cwd)
- fatal("redo: failed to obtain cwd");
- if (setenv("REDO_ROOT", cwd, 0))
- fatal("redo: failed to setenv REDO_ROOT to %s", cwd);
- free(cwd);
-
- /* set REDO_MAGIC */
- srand(time(NULL));
- char magic_str[digits(UINT_MAX) + 1];
- sprintf(magic_str, "%u", rand());
- if (setenv("REDO_MAGIC", magic_str, 0))
- fatal("setenv()");
+ /* create the dependency store if it doesn't already exist */
+ if (mkdirp(".redo") && mkdirp(".redo/deps"))
+ fprintf(stderr, "redo: creating dependency store ...\n");
+
+ /* set REDO_ROOT */
+ char *cwd = getcwd(NULL, 0);
+ if (!cwd)
+ fatal("redo: failed to obtain cwd");
+ if (setenv("REDO_ROOT", cwd, 0))
+ fatal("redo: failed to setenv REDO_ROOT to %s", cwd);
+ free(cwd);
+
+ /* set REDO_MAGIC */
+ srand(time(NULL));
+ char magic_str[digits(UINT_MAX) + 1];
+ sprintf(magic_str, "%u", rand());
+ if (setenv("REDO_MAGIC", magic_str, 0))
+ fatal("setenv()");
}
int main(int argc, char *argv[]) {
- prepare_env();
-
- if (argc < 2) {
- build_target("all");
- } else {
- int i;
- for (i = 1; i < argc; ++i) {
- build_target(argv[i]);
- }
- }
+ prepare_env();
+
+ if (argc < 2) {
+ build_target("all");
+ } else {
+ int i;
+ for (i = 1; i < argc; ++i) {
+ build_target(argv[i]);
+ }
+ }
}
diff --git a/src/util.c b/src/util.c
index 5fc6d47..797c84d 100644
--- a/src/util.c
+++ b/src/util.c
@@ -16,54 +16,54 @@
void *safe_malloc_(size_t size, const char *file, unsigned line) {
- assert(size > 0);
- void *ptr = malloc(size);
- if (!ptr)
- fatal_(file, line, ERRM_MALLOC, size);
+ assert(size > 0);
+ void *ptr = malloc(size);
+ if (!ptr)
+ fatal_(file, line, ERRM_MALLOC, size);
- return ptr;
+ return ptr;
}
void *safe_realloc_(void *ptr, size_t size, const char *file, unsigned line) {
- assert(size > 0 && ptr);
- void *ptr2 = realloc(ptr, size);
- if (!ptr2)
- fatal_(file, line, ERRM_REALLOC, size);
+ assert(size > 0 && ptr);
+ void *ptr2 = realloc(ptr, size);
+ if (!ptr2)
+ fatal_(file, line, ERRM_REALLOC, size);
- return ptr2;
+ return ptr2;
}
char *safe_strdup_(const char *str, const char *file, unsigned line) {
- assert(str);
- size_t len = strlen(str) + 1;
- char *ptr = malloc(len);
- if (!ptr)
- fatal_(file, line, ERRM_MALLOC, len);
+ assert(str);
+ size_t len = strlen(str) + 1;
+ char *ptr = malloc(len);
+ if (!ptr)
+ fatal_(file, line, ERRM_MALLOC, len);
- return memcpy(ptr, str, len);
+ return memcpy(ptr, str, len);
}
/* For concating multiple strings into a single larger one. */
char *concat(size_t count, ...) {
- assert(count > 0);
- va_list ap, ap2;
- va_start(ap, count);
- va_copy(ap2, ap);
- size_t i, size = 0, args_len[count];
- for (i = 0; i < count; ++i) {
- args_len[i] = strlen(va_arg(ap, char*));
- size += args_len[i];
- }
- ++size;
- char *result = safe_malloc(size);
- /* debug("Allocated %zu bytes at %p\n", size, result); */
- uintptr_t offset = 0;
- for (i = 0; i < count; ++i) {
- strcpy(&result[offset], va_arg(ap2, char*));
- offset += args_len[i];
- }
- va_end(ap);
- va_end(ap2);
- return result;
+ assert(count > 0);
+ va_list ap, ap2;
+ va_start(ap, count);
+ va_copy(ap2, ap);
+ size_t i, size = 0, args_len[count];
+ for (i = 0; i < count; ++i) {
+ args_len[i] = strlen(va_arg(ap, char*));
+ size += args_len[i];
+ }
+ ++size;
+ char *result = safe_malloc(size);
+ /* debug("Allocated %zu bytes at %p\n", size, result); */
+ uintptr_t offset = 0;
+ for (i = 0; i < count; ++i) {
+ strcpy(&result[offset], va_arg(ap2, char*));
+ offset += args_len[i];
+ }
+ va_end(ap);
+ va_end(ap2);
+ return result;
}