git@vger.kernel.org list mirror (unofficial, one of many)
 help / color / Atom feed
From: Brandon Williams <bmwill@google.com>
To: git@vger.kernel.org, bmwill@google.com
Cc: Brandon Williams <bmwill@google.com>
Subject: [PATCH 02/35] refspec: factor out parsing a single refspec
Date: Mon, 14 May 2018 14:55:53 -0700
Message-ID: <20180514215626.164960-3-bmwill@google.com> (raw)
In-Reply-To: <20180514215626.164960-1-bmwill@google.com>

Factor out the logic which parses a single refspec into its own
function.  This makes it easier to reuse this logic in a future patch.

Signed-off-by: Brandon Williams <bmwill@google.com>
---
 refspec.c | 195 +++++++++++++++++++++++++++++-------------------------
 1 file changed, 104 insertions(+), 91 deletions(-)

diff --git a/refspec.c b/refspec.c
index ecb0bdff3..3cfcbd37d 100644
--- a/refspec.c
+++ b/refspec.c
@@ -14,110 +14,123 @@ static struct refspec s_tag_refspec = {
 /* See TAG_REFSPEC for the string version */
 const struct refspec *tag_refspec = &s_tag_refspec;
 
-static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
+/*
+ * Parses 'refspec' and populates 'rs'.  returns 1 if successful and 0 if the
+ * refspec is invalid.
+ */
+static int parse_refspec(struct refspec *rs, const char *refspec, int fetch)
 {
-	int i;
-	struct refspec *rs = xcalloc(nr_refspec, sizeof(*rs));
+	size_t llen;
+	int is_glob;
+	const char *lhs, *rhs;
+	int flags;
 
-	for (i = 0; i < nr_refspec; i++) {
-		size_t llen;
-		int is_glob;
-		const char *lhs, *rhs;
-		int flags;
+	is_glob = 0;
 
-		is_glob = 0;
+	lhs = refspec;
+	if (*lhs == '+') {
+		rs->force = 1;
+		lhs++;
+	}
 
-		lhs = refspec[i];
-		if (*lhs == '+') {
-			rs[i].force = 1;
-			lhs++;
-		}
+	rhs = strrchr(lhs, ':');
 
-		rhs = strrchr(lhs, ':');
+	/*
+	 * Before going on, special case ":" (or "+:") as a refspec
+	 * for pushing matching refs.
+	 */
+	if (!fetch && rhs == lhs && rhs[1] == '\0') {
+		rs->matching = 1;
+		return 1;
+	}
 
+	if (rhs) {
+		size_t rlen = strlen(++rhs);
+		is_glob = (1 <= rlen && strchr(rhs, '*'));
+		rs->dst = xstrndup(rhs, rlen);
+	}
+
+	llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
+	if (1 <= llen && memchr(lhs, '*', llen)) {
+		if ((rhs && !is_glob) || (!rhs && fetch))
+			return 0;
+		is_glob = 1;
+	} else if (rhs && is_glob) {
+		return 0;
+	}
+
+	rs->pattern = is_glob;
+	rs->src = xstrndup(lhs, llen);
+	flags = REFNAME_ALLOW_ONELEVEL | (is_glob ? REFNAME_REFSPEC_PATTERN : 0);
+
+	if (fetch) {
+		struct object_id unused;
+
+		/* LHS */
+		if (!*rs->src)
+			; /* empty is ok; it means "HEAD" */
+		else if (llen == GIT_SHA1_HEXSZ && !get_oid_hex(rs->src, &unused))
+			rs->exact_sha1 = 1; /* ok */
+		else if (!check_refname_format(rs->src, flags))
+			; /* valid looking ref is ok */
+		else
+			return 0;
+		/* RHS */
+		if (!rs->dst)
+			; /* missing is ok; it is the same as empty */
+		else if (!*rs->dst)
+			; /* empty is ok; it means "do not store" */
+		else if (!check_refname_format(rs->dst, flags))
+			; /* valid looking ref is ok */
+		else
+			return 0;
+	} else {
 		/*
-		 * Before going on, special case ":" (or "+:") as a refspec
-		 * for pushing matching refs.
+		 * LHS
+		 * - empty is allowed; it means delete.
+		 * - when wildcarded, it must be a valid looking ref.
+		 * - otherwise, it must be an extended SHA-1, but
+		 *   there is no existing way to validate this.
 		 */
-		if (!fetch && rhs == lhs && rhs[1] == '\0') {
-			rs[i].matching = 1;
-			continue;
+		if (!*rs->src)
+			; /* empty is ok */
+		else if (is_glob) {
+			if (check_refname_format(rs->src, flags))
+				return 0;
 		}
-
-		if (rhs) {
-			size_t rlen = strlen(++rhs);
-			is_glob = (1 <= rlen && strchr(rhs, '*'));
-			rs[i].dst = xstrndup(rhs, rlen);
+		else
+			; /* anything goes, for now */
+		/*
+		 * RHS
+		 * - missing is allowed, but LHS then must be a
+		 *   valid looking ref.
+		 * - empty is not allowed.
+		 * - otherwise it must be a valid looking ref.
+		 */
+		if (!rs->dst) {
+			if (check_refname_format(rs->src, flags))
+				return 0;
+		} else if (!*rs->dst) {
+			return 0;
+		} else {
+			if (check_refname_format(rs->dst, flags))
+				return 0;
 		}
+	}
 
-		llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
-		if (1 <= llen && memchr(lhs, '*', llen)) {
-			if ((rhs && !is_glob) || (!rhs && fetch))
-				goto invalid;
-			is_glob = 1;
-		} else if (rhs && is_glob) {
-			goto invalid;
-		}
+	return 1;
+}
 
-		rs[i].pattern = is_glob;
-		rs[i].src = xstrndup(lhs, llen);
-		flags = REFNAME_ALLOW_ONELEVEL | (is_glob ? REFNAME_REFSPEC_PATTERN : 0);
-
-		if (fetch) {
-			struct object_id unused;
-
-			/* LHS */
-			if (!*rs[i].src)
-				; /* empty is ok; it means "HEAD" */
-			else if (llen == GIT_SHA1_HEXSZ && !get_oid_hex(rs[i].src, &unused))
-				rs[i].exact_sha1 = 1; /* ok */
-			else if (!check_refname_format(rs[i].src, flags))
-				; /* valid looking ref is ok */
-			else
-				goto invalid;
-			/* RHS */
-			if (!rs[i].dst)
-				; /* missing is ok; it is the same as empty */
-			else if (!*rs[i].dst)
-				; /* empty is ok; it means "do not store" */
-			else if (!check_refname_format(rs[i].dst, flags))
-				; /* valid looking ref is ok */
-			else
-				goto invalid;
-		} else {
-			/*
-			 * LHS
-			 * - empty is allowed; it means delete.
-			 * - when wildcarded, it must be a valid looking ref.
-			 * - otherwise, it must be an extended SHA-1, but
-			 *   there is no existing way to validate this.
-			 */
-			if (!*rs[i].src)
-				; /* empty is ok */
-			else if (is_glob) {
-				if (check_refname_format(rs[i].src, flags))
-					goto invalid;
-			}
-			else
-				; /* anything goes, for now */
-			/*
-			 * RHS
-			 * - missing is allowed, but LHS then must be a
-			 *   valid looking ref.
-			 * - empty is not allowed.
-			 * - otherwise it must be a valid looking ref.
-			 */
-			if (!rs[i].dst) {
-				if (check_refname_format(rs[i].src, flags))
-					goto invalid;
-			} else if (!*rs[i].dst) {
-				goto invalid;
-			} else {
-				if (check_refname_format(rs[i].dst, flags))
-					goto invalid;
-			}
-		}
+static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
+{
+	int i;
+	struct refspec *rs = xcalloc(nr_refspec, sizeof(*rs));
+
+	for (i = 0; i < nr_refspec; i++) {
+		if (!parse_refspec(&rs[i], refspec[i], fetch))
+			goto invalid;
 	}
+
 	return rs;
 
  invalid:
-- 
2.17.0.441.gb46fe60e1d-goog


  parent reply index

Thread overview: 112+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-14 21:55 [PATCH 00/35] refactoring refspecs Brandon Williams
2018-05-14 21:55 ` [PATCH 01/35] refspec: move refspec parsing logic into its own file Brandon Williams
2018-05-15  8:06   ` Junio C Hamano
2018-05-15 16:51     ` Brandon Williams
2018-05-16  0:40       ` Junio C Hamano
2018-05-14 21:55 ` Brandon Williams [this message]
2018-05-14 21:55 ` [PATCH 03/35] refspec: rename struct refspec to struct refspec_item Brandon Williams
2018-05-15  8:17   ` Junio C Hamano
2018-05-15 18:19     ` Brandon Williams
2018-05-14 21:55 ` [PATCH 04/35] refspec: introduce struct refspec Brandon Williams
2018-05-15  9:37   ` Junio C Hamano
2018-05-15 18:37     ` Brandon Williams
2018-05-14 21:55 ` [PATCH 05/35] refspec: convert valid_fetch_refspec to use parse_refspec Brandon Williams
2018-05-15  9:41   ` Junio C Hamano
2018-05-14 21:55 ` [PATCH 06/35] submodule--helper: convert push_check to use struct refspec Brandon Williams
2018-05-14 21:55 ` [PATCH 07/35] pull: convert get_tracking_branch to use refspec_item_init Brandon Williams
2018-05-14 21:55 ` [PATCH 08/35] transport: convert transport_push to use struct refspec Brandon Williams
2018-05-14 21:56 ` [PATCH 09/35] remote: convert check_push_refs " Brandon Williams
2018-05-14 21:56 ` [PATCH 10/35] remote: convert match_push_refs " Brandon Williams
2018-05-14 21:56 ` [PATCH 11/35] clone: convert cmd_clone to use refspec_item_init Brandon Williams
2018-05-14 21:56 ` [PATCH 12/35] fast-export: convert to use struct refspec Brandon Williams
2018-05-14 21:56 ` [PATCH 13/35] remote: convert push refspecs to " Brandon Williams
2018-05-14 21:56 ` [PATCH 14/35] remote: convert fetch " Brandon Williams
2018-05-15  8:31   ` Ævar Arnfjörð Bjarmason
2018-05-15 17:57     ` Brandon Williams
2018-05-14 21:56 ` [PATCH 15/35] transport-helper: convert to use " Brandon Williams
2018-05-14 21:56 ` [PATCH 16/35] fetch: convert fetch_one " Brandon Williams
2018-05-14 21:56 ` [PATCH 17/35] fetch: convert refmap " Brandon Williams
2018-05-14 21:56 ` [PATCH 18/35] refspec: remove the deprecated functions Brandon Williams
2018-05-14 21:56 ` [PATCH 19/35] fetch: convert do_fetch to take a struct refspec Brandon Williams
2018-05-14 21:56 ` [PATCH 20/35] fetch: convert get_ref_map " Brandon Williams
2018-05-14 21:56 ` [PATCH 21/35] fetch: convert prune_refs " Brandon Williams
2018-05-14 21:56 ` [PATCH 22/35] remote: convert get_stale_heads " Brandon Williams
2018-05-14 21:56 ` [PATCH 23/35] remote: convert apply_refspecs " Brandon Williams
2018-05-14 21:56 ` [PATCH 24/35] remote: convert query_refspecs " Brandon Williams
2018-05-14 21:56 ` [PATCH 25/35] remote: convert get_ref_match " Brandon Williams
2018-05-14 21:56 ` [PATCH 26/35] remote: convert match_explicit_refs " Brandon Williams
2018-05-14 21:56 ` [PATCH 27/35] push: check for errors earlier Brandon Williams
2018-05-14 21:56 ` [PATCH 28/35] push: convert to use struct refspec Brandon Williams
2018-05-14 21:56 ` [PATCH 29/35] transport: convert transport_push to take a " Brandon Williams
2018-05-14 21:56 ` [PATCH 30/35] send-pack: store refspecs in " Brandon Williams
2018-05-14 21:56 ` [PATCH 31/35] transport: remove transport_verify_remote_names Brandon Williams
2018-05-14 21:56 ` [PATCH 32/35] http-push: store refspecs in a struct refspec Brandon Williams
2018-05-14 21:56 ` [PATCH 33/35] remote: convert match_push_refs to take " Brandon Williams
2018-05-14 21:56 ` [PATCH 34/35] remote: convert check_push_refs " Brandon Williams
2018-05-14 21:56 ` [PATCH 35/35] submodule: convert push_unpushed_submodules " Brandon Williams
2018-05-15  8:11   ` Ævar Arnfjörð Bjarmason
2018-05-15 16:52     ` Stefan Beller
2018-05-15 16:59     ` Brandon Williams
2018-05-14 23:08 ` [PATCH 00/35] refactoring refspecs Stefan Beller
2018-05-15  8:05 ` Junio C Hamano
2018-05-15  8:39 ` Ævar Arnfjörð Bjarmason
2018-05-15 18:01   ` Brandon Williams
2018-05-16 22:57 ` [PATCH v2 00/36] " Brandon Williams
2018-05-16 22:57   ` [PATCH v2 01/36] refspec: move refspec parsing logic into its own file Brandon Williams
2018-05-16 22:57   ` [PATCH v2 02/36] refspec: rename struct refspec to struct refspec_item Brandon Williams
2018-05-16 22:57   ` [PATCH v2 03/36] refspec: factor out parsing a single refspec Brandon Williams
2018-05-16 22:57   ` [PATCH v2 04/36] refspec: introduce struct refspec Brandon Williams
2018-05-16 22:57   ` [PATCH v2 05/36] refspec: convert valid_fetch_refspec to use parse_refspec Brandon Williams
2018-06-03 17:13     ` Martin Ågren
2018-06-04 14:43       ` [PATCH] refspec: initalize `refspec_item` in `valid_fetch_refspec()` Martin Ågren
2018-06-04 17:36         ` Brandon Williams
2018-06-04 21:55         ` Ævar Arnfjörð Bjarmason
2018-06-05  5:10           ` Martin Ågren
2018-06-05 16:29           ` Brandon Williams
2018-06-05 19:54             ` [PATCH 0/3] refspec: refactor & fix free() behavior Ævar Arnfjörð Bjarmason
2018-06-05 19:58               ` Brandon Williams
2018-06-05 20:20                 ` Martin Ågren
2018-06-05 19:54             ` [PATCH 1/3] refspec: s/refspec_item_init/&_or_die/g Ævar Arnfjörð Bjarmason
2018-06-05 19:54             ` [PATCH 2/3] refspec: add back a refspec_item_init() function Ævar Arnfjörð Bjarmason
2018-06-05 19:54             ` [PATCH 3/3] refspec: initalize `refspec_item` in `valid_fetch_refspec()` Ævar Arnfjörð Bjarmason
2018-05-16 22:57   ` [PATCH v2 06/36] submodule--helper: convert push_check to use struct refspec Brandon Williams
2018-05-16 22:57   ` [PATCH v2 07/36] pull: convert get_tracking_branch to use refspec_item_init Brandon Williams
2018-05-16 22:57   ` [PATCH v2 08/36] transport: convert transport_push to use struct refspec Brandon Williams
2018-05-16 22:57   ` [PATCH v2 09/36] remote: convert check_push_refs " Brandon Williams
2018-05-16 22:57   ` [PATCH v2 10/36] remote: convert match_push_refs " Brandon Williams
2018-05-16 22:57   ` [PATCH v2 11/36] clone: convert cmd_clone to use refspec_item_init Brandon Williams
2018-05-16 22:57   ` [PATCH v2 12/36] fast-export: convert to use struct refspec Brandon Williams
2018-05-16 22:58   ` [PATCH v2 13/36] remote: convert push refspecs to " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 14/36] remote: convert fetch " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 15/36] remote: remove add_prune_tags_to_fetch_refspec Brandon Williams
2018-05-16 22:58   ` [PATCH v2 16/36] transport-helper: convert to use struct refspec Brandon Williams
2018-05-16 22:58   ` [PATCH v2 17/36] fetch: convert fetch_one " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 18/36] fetch: convert refmap " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 19/36] refspec: remove the deprecated functions Brandon Williams
2018-05-16 22:58   ` [PATCH v2 20/36] fetch: convert do_fetch to take a struct refspec Brandon Williams
2018-05-16 22:58   ` [PATCH v2 21/36] fetch: convert get_ref_map " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 22/36] fetch: convert prune_refs " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 23/36] remote: convert get_stale_heads " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 24/36] remote: convert apply_refspecs " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 25/36] remote: convert query_refspecs " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 26/36] remote: convert get_ref_match " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 27/36] remote: convert match_explicit_refs " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 28/36] push: check for errors earlier Brandon Williams
2018-05-16 22:58   ` [PATCH v2 29/36] push: convert to use struct refspec Brandon Williams
2018-05-16 22:58   ` [PATCH v2 30/36] transport: convert transport_push to take a " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 31/36] send-pack: store refspecs in " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 32/36] transport: remove transport_verify_remote_names Brandon Williams
2018-05-16 22:58   ` [PATCH v2 33/36] http-push: store refspecs in a struct refspec Brandon Williams
2018-05-16 22:58   ` [PATCH v2 34/36] remote: convert match_push_refs to take " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 35/36] remote: convert check_push_refs " Brandon Williams
2018-05-16 22:58   ` [PATCH v2 36/36] submodule: convert push_unpushed_submodules " Brandon Williams
2018-05-16 23:48   ` [PATCH 0/2] generating ref-prefixes for configured refspecs Brandon Williams
2018-05-16 23:48     ` [PATCH 1/2] refspec: consolidate ref-prefix generation logic Brandon Williams
2018-05-31  0:43       ` Jonathan Nieder
2018-05-31  1:07         ` Jonathan Nieder
2018-05-31  7:23       ` [PATCH] fetch: do not pass ref-prefixes for fetch by exact SHA1 Jonathan Nieder
2018-05-31 15:44         ` Brandon Williams
2018-06-01  2:12         ` Junio C Hamano
2018-06-01  2:49           ` Jonathan Nieder
2018-05-16 23:48     ` [PATCH 2/2] fetch: generate ref-prefixes when using a configured refspec Brandon Williams
2018-05-17 21:32     ` [PATCH 0/2] generating ref-prefixes for configured refspecs Junio C Hamano

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180514215626.164960-3-bmwill@google.com \
    --to=bmwill@google.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

git@vger.kernel.org list mirror (unofficial, one of many)

Archives are clonable:
	git clone --mirror https://public-inbox.org/git
	git clone --mirror http://ou63pmih66umazou.onion/git
	git clone --mirror http://czquwvybam4bgbro.onion/git
	git clone --mirror http://hjrcffqmbrq6wope.onion/git

Example config snippet for mirrors

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.version-control.git
	nntp://ou63pmih66umazou.onion/inbox.comp.version-control.git
	nntp://czquwvybam4bgbro.onion/inbox.comp.version-control.git
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.version-control.git
	nntp://news.gmane.org/gmane.comp.version-control.git

 note: .onion URLs require Tor: https://www.torproject.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox