Am 18.12.2013 15:53, schrieb Nguyễn Thái Ngọc Duy:
> I reimplemented skip_prefix() again just to realize this function
> already exists. Which reminds me there are a bunch of places that
> could benefit from this function, the same reason that I wanted to
> reimplement it.
> 
> So this is series to make it more popular (so hopefully I'll see it
> used somewhere and know that it exists) and the code cleaner. The
> pattern "compare a string, then skip the compared part by a hard coded
> string length" is almost killed. I left a few in places for those who
> want to contribute :)

Good idea.

Seeing that skip_prefix_defval is mostly used in the form
skip_prefix_defval(foo, prefix, foo) I wonder if it makes sense to
first change skip_prefix to return the full string instead of NULL
if the prefix is not matched.  Would the resulting function cover
most use cases?  And would it still be easily usable?

---
 advice.c                   |  2 ++
 builtin/branch.c           |  6 +++---
 builtin/clone.c            |  6 ++++--
 builtin/commit.c           |  6 ++----
 builtin/fmt-merge-msg.c    |  6 +++---
 builtin/push.c             |  2 --
 builtin/remote.c           | 13 +++----------
 column.c                   |  2 +-
 config.c                   |  2 +-
 credential-cache--daemon.c |  4 ++--
 credential.c               |  2 +-
 git-compat-util.h          |  7 +------
 parse-options.c            | 11 ++++++-----
 strbuf.c                   | 10 ++++++++++
 transport.c                |  6 +++++-
 urlmatch.c                 |  2 +-
 16 files changed, 45 insertions(+), 42 deletions(-)

diff --git a/advice.c b/advice.c
index 3eca9f5..1f85338 100644
--- a/advice.c
+++ b/advice.c
@@ -66,6 +66,8 @@ int git_default_advice_config(const char *var, const char 
*value)
        const char *k = skip_prefix(var, "advice.");
        int i;
 
+       if (k == var)
+               return 0;
        for (i = 0; i < ARRAY_SIZE(advice_config); i++) {
                if (strcmp(k, advice_config[i].name))
                        continue;
diff --git a/builtin/branch.c b/builtin/branch.c
index b4d7716..d3694d0 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -294,13 +294,13 @@ static char *resolve_symref(const char *src, const char 
*prefix)
 {
        unsigned char sha1[20];
        int flag;
-       const char *dst, *cp;
+       const char *dst;
 
        dst = resolve_ref_unsafe(src, sha1, 0, &flag);
        if (!(dst && (flag & REF_ISSYMREF)))
                return NULL;
-       if (prefix && (cp = skip_prefix(dst, prefix)))
-               dst = cp;
+       if (prefix)
+               dst = skip_prefix(dst, prefix);
        return xstrdup(dst);
 }
 
diff --git a/builtin/clone.c b/builtin/clone.c
index f98f529..79f24cd 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -578,11 +578,13 @@ static void update_remote_refs(const struct ref *refs,
 static void update_head(const struct ref *our, const struct ref *remote,
                        const char *msg)
 {
-       if (our && starts_with(our->name, "refs/heads/")) {
+       const char *head;
+
+       if (our &&
+           ((head = skip_prefix(our->name, "refs/heads/")) != our->name)) {
                /* Local default branch link */
                create_symref("HEAD", our->name, NULL);
                if (!option_bare) {
-                       const char *head = skip_prefix(our->name, 
"refs/heads/");
                        update_ref(msg, "HEAD", our->old_sha1, NULL, 0, 
DIE_ON_ERR);
                        install_branch_config(0, head, option_origin, 
our->name);
                }
diff --git a/builtin/commit.c b/builtin/commit.c
index 3767478..c18a77d 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -934,7 +934,7 @@ static int message_is_empty(struct strbuf *sb)
 static int template_untouched(struct strbuf *sb)
 {
        struct strbuf tmpl = STRBUF_INIT;
-       char *start;
+       const char *start;
 
        if (cleanup_mode == CLEANUP_NONE && sb->len)
                return 0;
@@ -943,9 +943,7 @@ static int template_untouched(struct strbuf *sb)
                return 0;
 
        stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
-       start = (char *)skip_prefix(sb->buf, tmpl.buf);
-       if (!start)
-               start = sb->buf;
+       start = skip_prefix(sb->buf, tmpl.buf);
        strbuf_release(&tmpl);
        return rest_is_empty(sb, start - sb->buf);
 }
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 3906eda..ff34c62 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -284,7 +284,7 @@ static void credit_people(struct strbuf *out,
                          int kind)
 {
        const char *label;
-       const char *me;
+       const char *me, *p;
 
        if (kind == 'a') {
                label = "By";
@@ -297,8 +297,8 @@ static void credit_people(struct strbuf *out,
        if (!them->nr ||
            (them->nr == 1 &&
             me &&
-            (me = skip_prefix(me, them->items->string)) != NULL &&
-            skip_prefix(me, " <")))
+            (p = skip_prefix(me, them->items->string)) != me &&
+            starts_with(p, " <")))
                return;
        strbuf_addf(out, "\n%c %s ", comment_line_char, label);
        add_people_count(out, them);
diff --git a/builtin/push.c b/builtin/push.c
index a73982a..2852a46 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -91,8 +91,6 @@ static NORETURN int die_push_simple(struct branch *branch, 
struct remote *remote
        const char *short_upstream =
                skip_prefix(branch->merge[0]->src, "refs/heads/");
 
-       if (!short_upstream)
-               short_upstream = branch->merge[0]->src;
        /*
         * Don't show advice for people who explicitly set
         * push.default.
diff --git a/builtin/remote.c b/builtin/remote.c
index b3ab4cf..1f5dfbe 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -248,14 +248,7 @@ struct branch_info {
 
 static struct string_list branch_list;
 
-static const char *abbrev_ref(const char *name, const char *prefix)
-{
-       const char *abbrev = skip_prefix(name, prefix);
-       if (abbrev)
-               return abbrev;
-       return name;
-}
-#define abbrev_branch(name) abbrev_ref((name), "refs/heads/")
+#define abbrev_branch(name) skip_prefix((name), "refs/heads/")
 
 static int config_read_branches(const char *key, const char *value, void *cb)
 {
@@ -1326,10 +1319,10 @@ static int prune_remote(const char *remote, int dry_run)
 
                if (dry_run)
                        printf_ln(_(" * [would prune] %s"),
-                              abbrev_ref(refname, "refs/remotes/"));
+                              skip_prefix(refname, "refs/remotes/"));
                else
                        printf_ln(_(" * [pruned] %s"),
-                              abbrev_ref(refname, "refs/remotes/"));
+                              skip_prefix(refname, "refs/remotes/"));
                warn_dangling_symref(stdout, dangling_msg, refname);
        }
 
diff --git a/column.c b/column.c
index 9367ba5..7de051d 100644
--- a/column.c
+++ b/column.c
@@ -337,7 +337,7 @@ int git_column_config(const char *var, const char *value,
                      const char *command, unsigned int *colopts)
 {
        const char *it = skip_prefix(var, "column.");
-       if (!it)
+       if (it == var)
                return 0;
 
        if (!strcmp(it, "ui"))
diff --git a/config.c b/config.c
index d969a5a..b787f8d 100644
--- a/config.c
+++ b/config.c
@@ -134,7 +134,7 @@ int git_config_include(const char *var, const char *value, 
void *data)
                return ret;
 
        type = skip_prefix(var, "include.");
-       if (!type)
+       if (type == var)
                return ret;
 
        if (!strcmp(type, "path"))
diff --git a/credential-cache--daemon.c b/credential-cache--daemon.c
index 390f194..21aad75 100644
--- a/credential-cache--daemon.c
+++ b/credential-cache--daemon.c
@@ -110,13 +110,13 @@ static int read_request(FILE *fh, struct credential *c,
 
        strbuf_getline(&item, fh, '\n');
        p = skip_prefix(item.buf, "action=");
-       if (!p)
+       if (p == item.buf)
                return error("client sent bogus action line: %s", item.buf);
        strbuf_addstr(action, p);
 
        strbuf_getline(&item, fh, '\n');
        p = skip_prefix(item.buf, "timeout=");
-       if (!p)
+       if (p == item.buf)
                return error("client sent bogus timeout line: %s", item.buf);
        *timeout = atoi(p);
 
diff --git a/credential.c b/credential.c
index e54753c..466beff 100644
--- a/credential.c
+++ b/credential.c
@@ -41,7 +41,7 @@ static int credential_config_callback(const char *var, const 
char *value,
        const char *key, *dot;
 
        key = skip_prefix(var, "credential.");
-       if (!key)
+       if (key == var)
                return 0;
 
        if (!value)
diff --git a/git-compat-util.h b/git-compat-util.h
index b73916b..dcb92c4 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -354,12 +354,7 @@ extern int starts_with(const char *str, const char 
*prefix);
 extern int prefixcmp(const char *str, const char *prefix);
 extern int ends_with(const char *str, const char *suffix);
 extern int suffixcmp(const char *str, const char *suffix);
-
-static inline const char *skip_prefix(const char *str, const char *prefix)
-{
-       size_t len = strlen(prefix);
-       return strncmp(str, prefix, len) ? NULL : str + len;
-}
+extern const char *skip_prefix(const char *str, const char *prefix);
 
 #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
 
diff --git a/parse-options.c b/parse-options.c
index 7b8d3fa..4ec2fa3 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -240,7 +240,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const 
char *arg,
 again:
                rest = skip_prefix(arg, long_name);
                if (options->type == OPTION_ARGUMENT) {
-                       if (!rest)
+                       if (rest == arg)
                                continue;
                        if (*rest == '=')
                                return opterror(options, "takes no value", 
flags);
@@ -249,7 +249,7 @@ again:
                        p->out[p->cpidx++] = arg - 2;
                        return 0;
                }
-               if (!rest) {
+               if (rest == arg) {
                        /* abbreviated? */
                        if (!strncmp(long_name, arg, arg_end - arg)) {
 is_abbreviated:
@@ -289,10 +289,11 @@ is_abbreviated:
                        flags |= OPT_UNSET;
                        rest = skip_prefix(arg + 3, long_name);
                        /* abbreviated and negated? */
-                       if (!rest && starts_with(long_name, arg + 3))
-                               goto is_abbreviated;
-                       if (!rest)
+                       if (rest == arg + 3) {
+                               if (starts_with(long_name, arg + 3))
+                                       goto is_abbreviated;
                                continue;
+                       }
                }
                if (*rest) {
                        if (*rest != '=')
diff --git a/strbuf.c b/strbuf.c
index 83caf4a..222df13 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -37,6 +37,16 @@ int suffixcmp(const char *str, const char *suffix)
                return strcmp(str + len - suflen, suffix);
 }
 
+const char *skip_prefix(const char *str, const char *prefix)
+{
+       const char *p;
+       for (p = str; ; p++, prefix++)
+               if (!*prefix)
+                       return p;
+               else if (*p != *prefix)
+                       return str;
+}
+
 /*
  * Used as the default ->buf value, so that people can always assume
  * buf is non NULL and ->buf is NUL terminated even for a freshly
diff --git a/transport.c b/transport.c
index 824c5b9..8d3372f 100644
--- a/transport.c
+++ b/transport.c
@@ -191,7 +191,11 @@ static void set_upstreams(struct transport *transport, 
struct ref *refs,
 
 static const char *rsync_url(const char *url)
 {
-       return !starts_with(url, "rsync://") ? skip_prefix(url, "rsync:") : url;
+       if (!starts_with(url, "rsync://")) {
+               const char *rest = skip_prefix(url, "rsync:");
+               url = (rest == url) ? NULL : rest;
+       }
+       return url;
 }
 
 static struct ref *get_refs_via_rsync(struct transport *transport, int 
for_push)
diff --git a/urlmatch.c b/urlmatch.c
index ec87cba..51b5d23 100644
--- a/urlmatch.c
+++ b/urlmatch.c
@@ -484,7 +484,7 @@ int urlmatch_config_entry(const char *var, const char 
*value, void *cb)
        int retval;
 
        key = skip_prefix(var, collect->section);
-       if (!key || *(key++) != '.') {
+       if ((key == var) || (*(key++) != '.')) {
                if (collect->cascade_fn)
                        return collect->cascade_fn(var, value, cb);
                return 0; /* not interested */
-- 
1.8.5.2


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to