aboutsummaryrefslogtreecommitdiff
path: root/ref-filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'ref-filter.c')
-rw-r--r--ref-filter.c65
1 files changed, 23 insertions, 42 deletions
diff --git a/ref-filter.c b/ref-filter.c
index 3917c4ccd9..6bbb6fac18 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -2173,32 +2173,34 @@ static inline char *copy_advance(char *dst, const char *src)
return dst;
}
-static const char *lstrip_ref_components(const char *refname, int len)
+static int normalize_component_count(const char *refname, int len)
{
- long remaining = len;
- const char *start = xstrdup(refname);
- const char *to_free = start;
-
if (len < 0) {
- int i;
- const char *p = refname;
+ int slashes = 0;
+
+ for (const char *p = refname; *p; p++) {
+ if (*p == '/')
+ slashes++;
+ }
- /* Find total no of '/' separated path-components */
- for (i = 0; p[i]; p[i] == '/' ? i++ : *p++)
- ;
/*
* The number of components we need to strip is now
* the total minus the components to be left (Plus one
* because we count the number of '/', but the number
* of components is one more than the no of '/').
*/
- remaining = i + len + 1;
+ len = slashes + len + 1;
}
+ return len;
+}
+
+static const char *lstrip_ref_components(const char *refname, int len)
+{
+ int remaining = normalize_component_count(refname, len);
while (remaining > 0) {
- switch (*start++) {
+ switch (*refname++) {
case '\0':
- free((char *)to_free);
return xstrdup("");
case '/':
remaining--;
@@ -2206,42 +2208,21 @@ static const char *lstrip_ref_components(const char *refname, int len)
}
}
- start = xstrdup(start);
- free((char *)to_free);
- return start;
+ return xstrdup(refname);
}
static const char *rstrip_ref_components(const char *refname, int len)
{
- long remaining = len;
- const char *start = xstrdup(refname);
- const char *to_free = start;
-
- if (len < 0) {
- int i;
- const char *p = refname;
+ int remaining = normalize_component_count(refname, len);
+ const char *end = refname + strlen(refname);
- /* Find total no of '/' separated path-components */
- for (i = 0; p[i]; p[i] == '/' ? i++ : *p++)
- ;
- /*
- * The number of components we need to strip is now
- * the total minus the components to be left (Plus one
- * because we count the number of '/', but the number
- * of components is one more than the no of '/').
- */
- remaining = i + len + 1;
- }
-
- while (remaining-- > 0) {
- char *p = strrchr(start, '/');
- if (!p) {
- free((char *)to_free);
+ while (remaining > 0) {
+ if (end == refname)
return xstrdup("");
- } else
- p[0] = '\0';
+ if (*--end == '/')
+ remaining--;
}
- return start;
+ return xmemdupz(refname, end - refname);
}
static const char *show_ref(struct refname_atom *atom, const char *refname)