Signed-off-by: Stefan Beller <sbel...@google.com>
---
 builtin/receive-pack.c | 13 +++++----
 connect.c              | 79 ++++++++++++++++++++++----------------------------
 connect.h              |  2 +-
 upload-pack.c          | 11 +++++--
 4 files changed, 51 insertions(+), 54 deletions(-)

diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index d2ec52b..518ce85 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1391,16 +1391,19 @@ static struct command *read_head_info(struct sha1_array 
*shallow)
 
                linelen = strlen(line);
                if (linelen < len) {
-                       const char *feature_list = line + linelen + 1;
-                       if (parse_feature_request(feature_list, 
"report-status"))
+                       struct string_list feature_list = STRING_LIST_INIT_DUP;
+                       from_space_separated_string(&feature_list, line + 
linelen + 1);
+                       if (parse_feature_request(&feature_list, 
"report-status"))
                                report_status = 1;
-                       if (parse_feature_request(feature_list, 
"side-band-64k"))
+                       if (parse_feature_request(&feature_list, 
"side-band-64k"))
                                use_sideband = LARGE_PACKET_MAX;
-                       if (parse_feature_request(feature_list, "quiet"))
+                       if (parse_feature_request(&feature_list, "quiet"))
                                quiet = 1;
                        if (advertise_atomic_push
-                           && parse_feature_request(feature_list, "atomic"))
+                           && parse_feature_request(&feature_list, "atomic"))
                                use_atomic = 1;
+
+                       string_list_clear(&feature_list, 1);
                }
 
                if (!strcmp(line, "push-cert")) {
diff --git a/connect.c b/connect.c
index c0144d8..4295ba1 100644
--- a/connect.c
+++ b/connect.c
@@ -10,8 +10,8 @@
 #include "string-list.h"
 #include "sha1-array.h"
 
-static char *server_capabilities;
-static const char *parse_feature_value(const char *, const char *, int *);
+struct string_list server_capabilities = STRING_LIST_INIT_DUP;
+static const char *parse_feature_value(struct string_list *, const char *, int 
*);
 
 static int check_ref(const char *name, unsigned int flags)
 {
@@ -80,18 +80,18 @@ reject:
 
 static void annotate_refs_with_symref_info(struct ref *ref)
 {
+       struct string_list_item *item;
        struct string_list symref = STRING_LIST_INIT_DUP;
-       const char *feature_list = server_capabilities;
 
-       while (feature_list) {
-               int len;
+       for_each_string_list_item(item, &server_capabilities) {
                const char *val;
 
-               val = parse_feature_value(feature_list, "symref", &len);
-               if (!val)
-                       break;
-               parse_one_symref_info(&symref, val, len);
-               feature_list = val + 1;
+               if (skip_prefix(item->string, "symref", &val)) {
+                       if (!val)
+                               continue;
+                       val++; /* skip the = */
+                       parse_one_symref_info(&symref, val, strlen(val));
+               }
        }
        string_list_sort(&symref);
 
@@ -153,8 +153,8 @@ struct ref **get_remote_heads(int in, char *src_buf, size_t 
src_len,
 
                name_len = strlen(name);
                if (len != name_len + 41) {
-                       free(server_capabilities);
-                       server_capabilities = xstrdup(name + name_len + 1);
+                       string_list_clear(&server_capabilities, 1);
+                       from_space_separated_string(&server_capabilities, name 
+ name_len + 1);
                }
 
                if (extra_have && !strcmp(name, ".have")) {
@@ -176,51 +176,40 @@ struct ref **get_remote_heads(int in, char *src_buf, 
size_t src_len,
        return list;
 }
 
-static const char *parse_feature_value(const char *feature_list, const char 
*feature, int *lenp)
+static const char *parse_feature_value(struct string_list *feature_list, const 
char *feature, int *lenp)
 {
-       int len;
-
-       if (!feature_list)
-               return NULL;
-
-       len = strlen(feature);
-       while (*feature_list) {
-               const char *found = strstr(feature_list, feature);
-               if (!found)
-                       return NULL;
-               if (feature_list == found || isspace(found[-1])) {
-                       const char *value = found + len;
-                       /* feature with no value (e.g., "thin-pack") */
-                       if (!*value || isspace(*value)) {
-                               if (lenp)
-                                       *lenp = 0;
-                               return value;
-                       }
-                       /* feature with a value (e.g., "agent=git/1.2.3") */
-                       else if (*value == '=') {
-                               value++;
-                               if (lenp)
-                                       *lenp = strcspn(value, " \t\n");
-                               return value;
-                       }
-                       /*
-                        * otherwise we matched a substring of another feature;
-                        * keep looking
-                        */
+       const char *value;
+       struct string_list_item *item;
+
+       for_each_string_list_item(item, feature_list) {
+               if (!skip_prefix(item->string, feature, &value))
+                       continue;
+
+               /* feature with no value (e.g., "thin-pack") */
+               if (!*value) {
+                       if (lenp)
+                               *lenp = 0;
+                       return value;
+               }
+               /* feature with a value (e.g., "agent=git/1.2.3") */
+               else if (*value == '=') {
+                       value++;
+                       if (lenp)
+                               *lenp = strlen(value);
+                       return value;
                }
-               feature_list = found + 1;
        }
        return NULL;
 }
 
-int parse_feature_request(const char *feature_list, const char *feature)
+int parse_feature_request(struct string_list *feature_list, const char 
*feature)
 {
        return !!parse_feature_value(feature_list, feature, NULL);
 }
 
 const char *server_feature_value(const char *feature, int *len)
 {
-       return parse_feature_value(server_capabilities, feature, len);
+       return parse_feature_value(&server_capabilities, feature, len);
 }
 
 int server_supports(const char *feature)
diff --git a/connect.h b/connect.h
index c41a685..47492e5 100644
--- a/connect.h
+++ b/connect.h
@@ -7,7 +7,7 @@ extern struct child_process *git_connect(int fd[2], const char 
*url, const char
 extern int finish_connect(struct child_process *conn);
 extern int git_connection_is_socket(struct child_process *conn);
 extern int server_supports(const char *feature);
-extern int parse_feature_request(const char *features, const char *feature);
+extern int parse_feature_request(struct string_list *, const char *feature);
 extern const char *server_feature_value(const char *feature, int *len_ret);
 extern int url_is_local_not_ssh(const char *url);
 
diff --git a/upload-pack.c b/upload-pack.c
index 5449ff7..2493964 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -531,7 +531,7 @@ error:
        }
 }
 
-static void parse_features(const char *features)
+static void parse_features(struct string_list *features)
 {
        if (parse_feature_request(features, "multi_ack_detailed"))
                multi_ack = 2;
@@ -563,7 +563,10 @@ static void receive_needs(void)
        for (;;) {
                struct object *o;
                unsigned char sha1_buf[20];
-               char *line = packet_read_line(0, NULL);
+               int pkt_len;
+               struct string_list list = STRING_LIST_INIT_DUP;
+               char *line = packet_read_line(0, &pkt_len);
+
                reset_timeout();
                if (!line)
                        break;
@@ -596,7 +599,9 @@ static void receive_needs(void)
                        die("git upload-pack: protocol error, "
                            "expected to get sha, not '%s'", line);
 
-               parse_features(line + 45);
+               from_space_separated_string(&list, xstrdup(line + 45));
+               parse_features(&list);
+               string_list_clear(&list, 1);
 
                o = parse_object(sha1_buf);
                if (!o)
-- 
2.4.1.345.gab207b6.dirty

--
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