Commit a62053a05061f9b107aceb5bda03e89990b038a7

Carlos Martín Nieto 2012-04-01T00:45:02

error-handling local transport

diff --git a/src/transports/local.c b/src/transports/local.c
index 6cf8ed9..fca8e64 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -26,115 +26,104 @@ static int add_ref(transport_local *t, const char *name)
 {
 	const char peeled[] = "^{}";
 	git_remote_head *head;
-	git_reference *ref, *resolved_ref;
-	git_object *obj = NULL, *peeled_tag_target = NULL;
-	int error = GIT_SUCCESS, peel_len, ret;
+	git_reference *ref = NULL, *resolved_ref = NULL;
+	git_object *obj = NULL, *target = NULL;
+	git_buf buf = GIT_BUF_INIT;
 
-	head = git__malloc(sizeof(git_remote_head));
-	if (head == NULL)
-		return GIT_ENOMEM;
+	if (git_reference_lookup(&ref, t->repo, name) < 0)
+		return -1;
 
-	head->name = git__strdup(name);
-	if (head->name == NULL) {
-		error = GIT_ENOMEM;
-		goto out;
+	if (git_reference_resolve(&resolved_ref, ref) < 0) {
+		git_reference_free(ref);
+		return -1;
 	}
 
-	error = git_reference_lookup(&ref, t->repo, name);
-	if (error < GIT_SUCCESS)
-		goto out;
+	head = git__malloc(sizeof(git_remote_head));
+	GITERR_CHECK_ALLOC(head);
 
-	error = git_reference_resolve(&resolved_ref, ref);
-	if (error < GIT_SUCCESS)
-		goto out;
+	head->name = git__strdup(name);
+	GITERR_CHECK_ALLOC(head->name);
 
 	git_oid_cpy(&head->oid, git_reference_oid(resolved_ref));
 
-	error = git_vector_insert(&t->refs, head);
-	if (error < GIT_SUCCESS)
-		goto out;
+	if (git_vector_insert(&t->refs, head) < 0)
+		return -1;
+
+	git_reference_free(ref);
+	git_reference_free(resolved_ref);
 
 	/* If it's not a tag, we don't need to try to peel it */
 	if (git__prefixcmp(name, GIT_REFS_TAGS_DIR))
-		goto out;
+		return 0;
 
-	error = git_object_lookup(&obj, t->repo, &head->oid, GIT_OBJ_ANY);
-	if (error < GIT_SUCCESS) {
-		git__rethrow(error, "Failed to lookup object");
-	}
+	if (git_object_lookup(&obj, t->repo, &head->oid, GIT_OBJ_ANY) < 0)
+		return -1;
 
 	head = NULL;
 
 	/* If it's not an annotated tag, just get out */
-	if (git_object_type(obj) != GIT_OBJ_TAG)
-		goto out;
+	if (git_object_type(obj) != GIT_OBJ_TAG) {
+		git_object_free(obj);
+		return 0;
+	}
 
 	/* And if it's a tag, peel it, and add it to the list */
 	head = git__malloc(sizeof(git_remote_head));
-	peel_len = strlen(name) + strlen(peeled);
-	head->name = git__malloc(peel_len + 1);
-	ret = p_snprintf(head->name, peel_len + 1, "%s%s", name, peeled);
+	GITERR_CHECK_ALLOC(head);
+	if (git_buf_join(&buf, 0, name, peeled) < 0)
+		return -1;
 
-	assert(ret < peel_len + 1);
-	(void)ret;
+	head->name = git_buf_detach(&buf);
 
-	error = git_tag_peel(&peeled_tag_target, (git_tag *) obj);
-	if (error < 0)
-		goto out;
+	if (git_tag_peel(&target, (git_tag *) obj) < 0)
+		goto on_error;
 
-	git_oid_cpy(&head->oid, git_object_id(peeled_tag_target));
+	git_oid_cpy(&head->oid, git_object_id(target));
+	git_object_free(obj);
+	git_object_free(target);
 
-	error = git_vector_insert(&t->refs, head);
-	if (error < GIT_SUCCESS)
-		goto out;
+	if (git_vector_insert(&t->refs, head) < 0)
+		return -1;
 
- out:
-	git_reference_free(ref);
-	git_reference_free(resolved_ref);
+	return 0;
 
+on_error:
 	git_object_free(obj);
-	git_object_free(peeled_tag_target);
-	if (head && error < GIT_SUCCESS) {
-		git__free(head->name);
-		git__free(head);
-	}
-
-	return error;
+	git_object_free(target);
+	return -1;
 }
 
 static int store_refs(transport_local *t)
 {
-	int error;
 	unsigned int i;
 	git_strarray ref_names = {0};
 
 	assert(t);
 
-	error = git_vector_init(&t->refs, ref_names.count, NULL);
-	if (error < GIT_SUCCESS)
-		return error;
+	if (git_vector_init(&t->refs, ref_names.count, NULL) < 0)
+		return -1;
 
-	error = git_reference_listall(&ref_names, t->repo, GIT_REF_LISTALL);
-	if (error < GIT_SUCCESS)
-		return git__rethrow(error, "Failed to list remote heads");
+	if (git_reference_listall(&ref_names, t->repo, GIT_REF_LISTALL) < 0)
+		goto on_error;
 
 	/* Sort the references first */
 	git__tsort((void **)ref_names.strings, ref_names.count, &git__strcmp_cb);
 
 	/* Add HEAD */
-	error = add_ref(t, GIT_HEAD_FILE);
-	if (error < GIT_SUCCESS)
-		goto cleanup;
+	if (add_ref(t, GIT_HEAD_FILE) < 0)
+		goto on_error;
 
 	for (i = 0; i < ref_names.count; ++i) {
-		error = add_ref(t, ref_names.strings[i]);
-		if (error < GIT_SUCCESS)
-			goto cleanup;
+		if (add_ref(t, ref_names.strings[i]) < 0)
+			goto on_error;
 	}
 
-cleanup:
+	return 0;
+
+on_error:
+	git_vector_free(&t->refs);
 	git_strarray_free(&ref_names);
-	return error;
+	return -1;
 }
 
 static int local_ls(git_transport *transport, git_headlist_cb list_cb, void *payload)
@@ -148,11 +137,10 @@ static int local_ls(git_transport *transport, git_headlist_cb list_cb, void *pay
 
 	git_vector_foreach(refs, i, h) {
 		if (list_cb(h, payload) < 0)
-			return git__throw(GIT_ERROR,
-				"The user callback returned an error code");
+			return -1;
 	}
 
-	return GIT_SUCCESS;
+	return 0;
 }
 
 /*
@@ -171,32 +159,31 @@ static int local_connect(git_transport *transport, int direction)
 
 	/* The repo layer doesn't want the prefix */
 	if (!git__prefixcmp(transport->url, "file://")) {
-		error = git_path_fromurl(&buf, transport->url);
-		if (error < GIT_SUCCESS) {
+		if (git_path_fromurl(&buf, transport->url) < 0) {
 			git_buf_free(&buf);
-			return git__rethrow(error, "Failed to parse remote path");
+			return -1;
 		}
 		path = git_buf_cstr(&buf);
 
-	} else /* We assume transport->url is already a path */
+	} else { /* We assume transport->url is already a path */
 		path = transport->url;
+	}
 
 	error = git_repository_open(&repo, path);
 
 	git_buf_free(&buf);
 
-	if (error < GIT_SUCCESS)
-		return git__rethrow(error, "Failed to open remote");
+	if (error < 0)
+		return -1;
 
 	t->repo = repo;
 
-	error = store_refs(t);
-	if (error < GIT_SUCCESS)
-		return git__rethrow(error, "Failed to retrieve references");
+	if (store_refs(t) < 0)
+		return -1;
 
 	t->parent.connected = 1;
 
-	return GIT_SUCCESS;
+	return 0;
 }
 
 static int local_close(git_transport *transport)
@@ -206,7 +193,7 @@ static int local_close(git_transport *transport)
 	git_repository_free(t->repo);
 	t->repo = NULL;
 
-	return GIT_SUCCESS;
+	return 0;
 }
 
 static void local_free(git_transport *transport)
@@ -237,8 +224,7 @@ int git_transport_local(git_transport **out)
 	transport_local *t;
 
 	t = git__malloc(sizeof(transport_local));
-	if (t == NULL)
-		return GIT_ENOMEM;
+	GITERR_CHECK_ALLOC(t);
 
 	memset(t, 0x0, sizeof(transport_local));
 
@@ -249,5 +235,5 @@ int git_transport_local(git_transport **out)
 
 	*out = (git_transport *) t;
 
-	return GIT_SUCCESS;
+	return 0;
 }