summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeder Andersen2012-11-12 18:46:49 (EST)
committer Eugene Tarassov2012-11-14 19:55:53 (EST)
commit97cf26b2a706e4967a2ab75a4f674bd50c7f6bda (patch)
treefd16236b1b915e746b9b59275df3eee85b391816
parent3c5dcc5a6066579032a045a03cf068bcdf41a0ff (diff)
downloadorg.eclipse.tcf.agent-97cf26b2a706e4967a2ab75a4f674bd50c7f6bda.zip
org.eclipse.tcf.agent-97cf26b2a706e4967a2ab75a4f674bd50c7f6bda.tar.gz
org.eclipse.tcf.agent-97cf26b2a706e4967a2ab75a4f674bd50c7f6bda.tar.bz2
pathmap: improve rule specification flexibility wrt trailing separators
If I have a path "target:/foo/bar.so" I want to map to "/foo/bar.so", I can use the rule: "target:", "" Alternatively, I could use the rule: "target:", "/" resulting in a slightly off, but usable "//foo/bar.so". However, what I can't do is use: "target:/", "/" or the less-strictly-correct: "target:/", "" Since pathmappings are very often entered by users directly, they are prone to inconsistencies, and in an effort to improve user-friendliness, this change adds support for the last case. In the process, it clarifies some of the logic and provides a fast-track for cases where the input filename matches the rule source completely.
-rw-r--r--agent/tcf/services/pathmap.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/agent/tcf/services/pathmap.c b/agent/tcf/services/pathmap.c
index 7363b60..cf1b863 100644
--- a/agent/tcf/services/pathmap.c
+++ b/agent/tcf/services/pathmap.c
@@ -344,16 +344,29 @@ static char * map_file_name(Context * ctx, PathMap * m, char * fnm, int mode) {
src = canonic_path_map_file_name(r->src);
k = (unsigned int) strlen(src);
if (strncmp(src, fnm, k)) continue;
- if (fnm[k] != 0 && fnm[k] != '/' && fnm[k] != '\\') {
- /* skip this rule only if it's not re-rooting the file-system */
- if ((k != 1) || (src[0] != '/')) continue;
- k = 0;
- }
- if (r->dst[0] != 0) {
- size_t j = strlen(r->dst) - 1;
- if (fnm[k] != 0 && (r->dst[j] == '/' || r->dst[j] == '\\')) k++;
+
+ if (fnm[k] == 0) {
+ /* perfect match */
+ buf = tmp_strdup(r->dst);
+ } else {
+ const size_t dst_len = strlen(r->dst);
+ const char last_dest_char = dst_len == 0 ? 0 : r->dst[dst_len - 1];
+ if (fnm[k] != '/' && fnm[k] != '\\') {
+ if (!(last_dest_char == '/' || last_dest_char == '\\')) {
+ const char last_src_char = k == 0 ? 0 : r->src[k - 1];
+ if (!(last_src_char == '/' || last_src_char == '\\'))
+ /* prevent matching mid-filename */
+ continue;
+ }
+ /* re-add initial path separator */
+ --k;
+ } else if (last_dest_char == '/' || last_dest_char == '\\')
+ /* strip extra path separator */
+ ++k;
+
+ buf = tmp_strdup2(r->dst, fnm + k);
}
- buf = tmp_strdup2(r->dst, fnm + k);
+
if (mode != PATH_MAP_TO_LOCAL || stat(buf, &st) == 0) return buf;
}