"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Tracey Emery <tracey@traceyemery.net>
Subject:
Re: Send/Fetch plumbing in parser
To:
gameoftrees@openbsd.org
Date:
Fri, 27 Aug 2021 10:23:51 -0600

Download raw body.

Thread
On Fri, Aug 27, 2021 at 06:09:51PM +0200, Stefan Sperling wrote:
> On Fri, Aug 27, 2021 at 09:49:22AM -0600, Tracey Emery wrote:
> > Hello,
> > 
> > This implements the parsing code needed to add fetch and send to
> > got.conf. I did not update the man page, since the fetch/send code
> > hasn't been written yet.
> > 
> > Ok?
> 
> > +fetch		: {
> > +			static const struct got_error* error;
> > +
> > +			error = new_fetch(&remote->fetch_repo);
> 
> What will happen if there are two or more fetch {} blocks in the file?
> Will data parsed from a previous block be overwritten and its memory leaked?
> 
> Should this code check for remote->fetch_repo != NULL and raise a
> syntax error if data for a fetch block has already been stored?
> Or is this being handled elsewhere somehow?
> 
> Same question applies to handling of the send {} block further below.
> 
> > +			if (error) {
> > +				yyerror("%s", error->msg);
> > +				YYERROR;
> > +			}

Ah yes, you're right. Good points. How about below?

-- 

Tracey Emery

diff 1bd76734ce8e567c3f156533dc1af31878bd5a65 /home/tracey/src/got
blob - 5f1429f97e35fc3f76e9a1054a203794f783e4c7
file + libexec/got-read-gotconfig/gotconfig.h
--- libexec/got-read-gotconfig/gotconfig.h
+++ libexec/got-read-gotconfig/gotconfig.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Tracey Emery <tracey@openbsd.org>
+ * Copyright (c) 2020, 2021 Tracey Emery <tracey@openbsd.org>
  * Copyright (c) 2020 Stefan Sperling <stsp@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -15,6 +15,24 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+struct fetch_repo {
+	char	*fetch_name;
+	char	*fetch_repository;
+	char	*fetch_server;
+	char	*fetch_protocol;
+	int	fetch_port;
+	struct	node_branch *fetch_branch;
+};
+
+struct send_repo {
+	char	*send_name;
+	char	*send_repository;
+	char	*send_server;
+	char	*send_protocol;
+	int	send_port;
+	struct	node_branch *send_branch;
+};
+
 struct node_branch {
 	char *branch_name;
 	struct node_branch *next;
@@ -38,6 +56,8 @@ struct gotconfig_remote_repo {
 	int	fetch_all_branches;
 	struct	node_branch *branch;
 	struct	node_ref *ref;
+	struct	fetch_repo *fetch_repo;
+	struct	send_repo *send_repo;
 };
 TAILQ_HEAD(gotconfig_remote_repo_list, gotconfig_remote_repo);
 
blob - 821eff3050b8f45ad0cd9b5475874eca2aa1117d
file + libexec/got-read-gotconfig/parse.y
--- libexec/got-read-gotconfig/parse.y
+++ libexec/got-read-gotconfig/parse.y
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Tracey Emery <tracey@openbsd.org>
+ * Copyright (c) 2020, 2021 Tracey Emery <tracey@openbsd.org>
  * Copyright (c) 2020 Stefan Sperling <stsp@openbsd.org>
  * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
  * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
@@ -81,6 +81,8 @@ static const struct got_error* gerror;
 static struct gotconfig_remote_repo *remote;
 static struct gotconfig gotconfig;
 static const struct got_error* new_remote(struct gotconfig_remote_repo **);
+static const struct got_error* new_fetch(struct fetch_repo **);
+static const struct got_error* new_send(struct send_repo **);
 
 typedef struct {
 	union {
@@ -96,7 +98,7 @@ typedef struct {
 
 %token	ERROR
 %token	REMOTE REPOSITORY SERVER PORT PROTOCOL MIRROR_REFERENCES BRANCH
-%token	AUTHOR FETCH_ALL_BRANCHES REFERENCE
+%token	AUTHOR FETCH_ALL_BRANCHES REFERENCE FETCH SEND
 %token	<v.string>	STRING
 %token	<v.number>	NUMBER
 %type	<v.number>	boolean portplain
@@ -231,7 +233,111 @@ remoteopts1	: REPOSITORY STRING {
 		| REFERENCE ref {
 			remote->ref = $2;
 		}
+		| FETCH fetch
+		| SEND send
 	   	;
+fetchopts2	: fetchopts2 fetchopts1 nl
+	   	| fetchopts1 optnl
+		;
+fetchopts1	: REPOSITORY STRING {
+	   		remote->fetch_repo->fetch_repository = strdup($2);
+			if (remote->fetch_repo->fetch_repository == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+	   	}
+	   	| SERVER STRING {
+	   		remote->fetch_repo->fetch_server = strdup($2);
+			if (remote->fetch_repo->fetch_server == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+		}
+		| PROTOCOL STRING {
+	   		remote->fetch_repo->fetch_protocol = strdup($2);
+			if (remote->fetch_repo->fetch_protocol == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+		}
+		| PORT portplain {
+			remote->fetch_repo->fetch_port = $2;
+		}
+		| BRANCH branch {
+			remote->fetch_repo->fetch_branch = $2;
+		}
+	   	;
+fetch		: {
+			static const struct got_error* error;
+
+			if (remote->fetch_repo != NULL) {
+				yyerror("fetch block already exists");
+				YYERROR;
+			}
+			error = new_fetch(&remote->fetch_repo);
+			if (error) {
+				yyerror("%s", error->msg);
+				YYERROR;
+			}
+		} '{' optnl fetchopts2 '}'
+       		;
+sendopts2	: sendopts2 sendopts1 nl
+	   	| sendopts1 optnl
+		;
+sendopts1	: REPOSITORY STRING {
+	   		remote->send_repo->send_repository = strdup($2);
+			if (remote->send_repo->send_repository == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+	   	}
+	   	| SERVER STRING {
+	   		remote->send_repo->send_server = strdup($2);
+			if (remote->send_repo->send_server == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+		}
+		| PROTOCOL STRING {
+	   		remote->send_repo->send_protocol = strdup($2);
+			if (remote->send_repo->send_protocol == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+		}
+		| PORT portplain {
+			remote->send_repo->send_port = $2;
+		}
+		| BRANCH branch {
+			remote->send_repo->send_branch = $2;
+		}
+	   	;
+send		: {
+			static const struct got_error* error;
+
+			if (remote->send_repo != NULL) {
+				yyerror("send block already exists");
+				YYERROR;
+			}
+			error = new_send(&remote->send_repo);
+			if (error) {
+				yyerror("%s", error->msg);
+				YYERROR;
+			}
+		} '{' optnl sendopts2 '}'
+       		;
 remote		: REMOTE STRING {
 			static const struct got_error* error;
 
@@ -314,6 +420,7 @@ lookup(char *s)
 	static const struct keywords keywords[] = {
 		{"author",		AUTHOR},
 		{"branch",		BRANCH},
+		{"fetch",		FETCH},
 		{"fetch-all-branches",	FETCH_ALL_BRANCHES},
 		{"mirror-references",	MIRROR_REFERENCES},
 		{"port",		PORT},
@@ -321,6 +428,7 @@ lookup(char *s)
 		{"reference",		REFERENCE},
 		{"remote",		REMOTE},
 		{"repository",		REPOSITORY},
+		{"send",		SEND},
 		{"server",		SERVER},
 	};
 	const struct keywords	*p;
@@ -661,6 +769,28 @@ new_remote(struct gotconfig_remote_repo **remote)
 	return error;
 }
 
+static const struct got_error*
+new_fetch(struct fetch_repo **fetch_repo)
+{
+	const struct got_error *error = NULL;
+
+	*fetch_repo = calloc(1, sizeof(**fetch_repo));
+	if (*fetch_repo == NULL)
+		error = got_error_from_errno("calloc");
+	return error;
+}
+
+static const struct got_error*
+new_send(struct send_repo **send_repo)
+{
+	const struct got_error *error = NULL;
+
+	*send_repo = calloc(1, sizeof(**send_repo));
+	if (*send_repo == NULL)
+		error = got_error_from_errno("calloc");
+	return error;
+}
+
 static void
 closefile(struct file *file)
 {
@@ -710,6 +840,18 @@ gotconfig_free(struct gotconfig *conf)
 	while (!TAILQ_EMPTY(&conf->remotes)) {
 		remote = TAILQ_FIRST(&conf->remotes);
 		TAILQ_REMOVE(&conf->remotes, remote, entry);
+		if (remote->fetch_repo != NULL) {
+			free(remote->fetch_repo->fetch_name);
+			free(remote->fetch_repo->fetch_repository);
+			free(remote->fetch_repo->fetch_server);
+			free(remote->fetch_repo->fetch_protocol);
+		}
+		if (remote->send_repo != NULL) {
+			free(remote->send_repo->send_name);
+			free(remote->send_repo->send_repository);
+			free(remote->send_repo->send_server);
+			free(remote->send_repo->send_protocol);
+		}
 		free(remote->name);
 		free(remote->repository);
 		free(remote->server);