diff options
| author | Tharre <tharre3@gmail.com> | 2015-02-15 01:50:48 +0100 | 
|---|---|---|
| committer | Tharre <tharre3@gmail.com> | 2015-02-15 01:53:16 +0100 | 
| commit | 575dcfc9e15cfbd45339fe0e5cb4be6c637248d1 (patch) | |
| tree | 3c16e5d3c38ded476323dcd596293aad68187c51 /src | |
| parent | 6fe2d9cb44515c4db53686327086f2ae894cad60 (diff) | |
| download | redo-575dcfc9e15cfbd45339fe0e5cb4be6c637248d1.tar.gz redo-575dcfc9e15cfbd45339fe0e5cb4be6c637248d1.tar.xz redo-575dcfc9e15cfbd45339fe0e5cb4be6c637248d1.zip  | |
Replace make_relative() with relpath()
Also improve the documentation for this function, and add a few
examples to clarify what it does (and what not).
Diffstat (limited to 'src')
| -rw-r--r-- | src/build.c | 4 | ||||
| -rw-r--r-- | src/filepath.c | 38 | ||||
| -rw-r--r-- | src/filepath.h | 2 | 
3 files changed, 25 insertions, 19 deletions
diff --git a/src/build.c b/src/build.c index c1dd602..71f10f9 100644 --- a/src/build.c +++ b/src/build.c @@ -322,9 +322,9 @@ static char *get_relpath(const char *target) {  	if (!abstarget)  		fatal("redo: failed to get realpath() of %s", target); -	char *relpath = xstrdup(make_relative(root, abstarget)); +	char *path = xstrdup(relpath(abstarget, root));  	free(abstarget); -	return relpath; +	return path;  }  /* Return the dependency file path of target. */ diff --git a/src/filepath.c b/src/filepath.c index d0b68de..e4d8e62 100644 --- a/src/filepath.c +++ b/src/filepath.c @@ -53,27 +53,33 @@ char *take_extension(const char *target) {  		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) { +/* Returns a pointer to a relative path to `path` from `start`. This pointer may +   be pointing to either of it's arguments, or to the statically allocated +   string "." should both paths match. Both paths must be canonicalized. +   A few examples: +    relpath("/abc/de", "/abc/de") => "." +    relpath("some/path/a/b/c", "some/path") => "a/b/c" +    relpath("some/path", "some/path/a/b/c") => "some/path/a/b/c" +    relpath("/", "/") => "." +    relpath("/abc", "/") => "abc" + */ +char *relpath(char *path, char *start) {  	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 "."; +	for (i = 0; path[i] && start[i]; ++i) { +		if (path[i] != start[i]) +			return path; /* paths share nothing */  	} -	/* skip any leading seperators */ -	while (to[i] == '/') +	if (!path[i] && start[i]) +		return start; /* path is above start */ + +	if (!path[i] && !start[i]) +		return "."; /* paths match completely */ + +	if (path[i] == '/')  		++i; -	return &to[i]; +	return &path[i];  }  /* Transforms target into a safe filename, replacing all '/' with '!'. */ diff --git a/src/filepath.h b/src/filepath.h index 3eb68ba..68a4ecf 100644 --- a/src/filepath.h +++ b/src/filepath.h @@ -14,7 +14,7 @@  extern bool is_absolute(const char* path);  extern char *remove_ext(const char *str);  extern char *take_extension(const char *target); -extern const char *make_relative(const char *target, const char *to); +extern char *relpath(char *path, char *start);  extern char *transform_path(const char *target);  extern char *xbasename(const char *path);  extern bool fexists(const char *target);  | 
