Download raw body.
Send/Fetch plumbing in parser
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);
Send/Fetch plumbing in parser