Download raw body.
Make gotweb config parsing work with last diff
Hello,
This builds on top of the last diff, making gotweb use the new library
function.
Ok?
--
Tracey Emery
diff refs/heads/parse refs/heads/gotweb
blob - 1bfc514197abcd84859f193604c899656ca61ca6
blob + dc5892fbfa8c426d4b371615a0b29585fd3e89f5
--- gotweb/gotweb.c
+++ gotweb/gotweb.c
@@ -31,6 +31,7 @@
#include <string.h>
#include <unistd.h>
+#include <got_error.h>
#include <got_object.h>
#include <got_reference.h>
#include <got_repository.h>
@@ -42,12 +43,11 @@
#include <got_blame.h>
#include <got_privsep.h>
#include <got_opentemp.h>
+#include "got_config_parse.h"
#include <kcgi.h>
#include <kcgihtml.h>
-#include "gotweb.h"
-
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
@@ -57,7 +57,7 @@ struct gw_trans {
TAILQ_HEAD(dirs, gw_dir) gw_dirs;
struct got_repository *repo;
struct gw_dir *gw_dir;
- struct gotweb_conf *gw_conf;
+ struct gotweb_config *gw_conf;
struct ktemplate *gw_tmpl;
struct khtmlreq *gw_html_req;
struct kreq *gw_req;
@@ -4656,7 +4656,7 @@ main(int argc, char *argv[])
}
if ((gw_trans->gw_conf =
- malloc(sizeof(struct gotweb_conf))) == NULL) {
+ malloc(sizeof(struct gotweb_config))) == NULL) {
gw_malloc = 0;
error = got_error_from_errno("malloc");
goto done;
@@ -4680,7 +4680,8 @@ main(int argc, char *argv[])
gw_trans->gw_tmpl->keysz = TEMPL__MAX;
gw_trans->gw_tmpl->arg = gw_trans;
gw_trans->gw_tmpl->cb = gw_template;
- error = parse_conf(GOTWEB_CONF, gw_trans->gw_conf);
+
+ error = got_config_parse_gotweb_config(&gw_trans->gw_conf, GOTWEB_CONF);
if (error)
goto done;
@@ -4700,7 +4701,6 @@ done:
free(gw_trans->gw_conf->got_site_link);
free(gw_trans->gw_conf->got_logo);
free(gw_trans->gw_conf->got_logo_url);
- free(gw_trans->gw_conf);
free(gw_trans->commit_id);
free(gw_trans->next_id);
free(gw_trans->next_prev_id);
blob - a2b02715b9a59a20e78eac7a01d868854f4fd3ac (mode 644)
blob + /dev/null
--- gotweb/gotweb.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2019, 2020 Tracey Emery <tracey@traceyemery.net>
- * Copyright (c) 2018, 2019 Stefan Sperling <stsp@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef GOTWEB_H
-#define GOTWEB_H
-
-#include <stdbool.h>
-
-#include <got_error.h>
-
-#define GOTWEB_CONF "/etc/gotweb.conf"
-#define GOTWEB_TMPL_DIR "/cgi-bin/gw_tmpl"
-#define GOTWEB "/cgi-bin/gotweb/gotweb"
-
-#define GOTWEB_GOT_DIR ".got"
-#define GOTWEB_GIT_DIR ".git"
-
-#define D_GOTPATH "/got/public"
-#define D_SITENAME "Gotweb"
-#define D_SITEOWNER "Got Owner"
-#define D_SITELINK "Repos"
-#define D_GOTLOGO "got.png"
-#define D_GOTURL "https://gameoftrees.org"
-
-#define D_SHOWROWNER true
-#define D_SHOWSOWNER true
-#define D_SHOWAGE true
-#define D_SHOWDESC true
-#define D_SHOWURL true
-#define D_MAXREPO 0
-#define D_MAXREPODISP 25
-#define D_MAXSLCOMMDISP 10
-#define D_MAXCOMMITDISP 25
-
-#define BUFFER_SIZE 2048
-
-struct gotweb_conf {
- char *got_repos_path;
- char *got_site_name;
- char *got_site_owner;
- char *got_site_link;
- char *got_logo;
- char *got_logo_url;
-
- size_t got_max_repos;
- size_t got_max_repos_display;
- size_t got_max_commits_display;
-
- bool got_show_site_owner;
- bool got_show_repo_owner;
- bool got_show_repo_age;
- bool got_show_repo_description;
- bool got_show_repo_cloneurl;
-};
-
-const struct got_error* parse_conf(const char *, struct gotweb_conf *);
-
-#endif /* GOTWEB_H */
blob - 2271bbde9b190920695f4451cfe046353cbe8ec7 (mode 644)
blob + /dev/null
--- gotweb/parse.y
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * Copyright (c) 2019 Tracey Emery <tracey@traceyemery.net>
- * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
- * Copyright (c) 2001 Markus Friedl. All rights reserved.
- * Copyright (c) 2001 Daniel Hartmeier. All rights reserved.
- * Copyright (c) 2001 Theo de Raadt. All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-%{
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "gotweb.h"
-
-TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
-static struct file {
- TAILQ_ENTRY(file) entry;
- FILE *stream;
- char *name;
- int lineno;
- int errors;
- const struct got_error* error;
-} *file, *topfile;
-struct file *pushfile(const char *);
-int popfile(void);
-int yyparse(void);
-int yylex(void);
-int yyerror(const char *, ...)
- __attribute__((__format__ (printf, 1, 2)))
- __attribute__((__nonnull__ (1)));
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-
-static const struct got_error* gerror = NULL;
-char *syn_err;
-
-struct gotweb_conf *gw_conf;
-
-typedef struct {
- union {
- int64_t number;
- char *string;
- } v;
- int lineno;
-} YYSTYPE;
-
-%}
-
-%token GOT_WWW_PATH GOT_MAX_REPOS GOT_SITE_NAME GOT_SITE_OWNER GOT_SITE_LINK
-%token GOT_LOGO GOT_LOGO_URL GOT_SHOW_REPO_OWNER GOT_SHOW_REPO_AGE
-%token GOT_SHOW_REPO_DESCRIPTION GOT_MAX_REPOS_DISPLAY GOT_REPOS_PATH
-%token GOT_MAX_COMMITS_DISPLAY ON ERROR GOT_SHOW_SITE_OWNER
-%token GOT_SHOW_REPO_CLONEURL
-%token <v.string> STRING
-%token <v.number> NUMBER
-%type <v.number> boolean
-%%
-
-grammar : /* empty */
- | grammar '\n'
- | grammar main '\n'
- | grammar error '\n' { file->errors++; }
- ;
-
-boolean : STRING {
- if (strcasecmp($1, "true") == 0 ||
- strcasecmp($1, "yes") == 0)
- $$ = 1;
- else if (strcasecmp($1, "false") == 0 ||
- strcasecmp($1, "off") == 0 ||
- strcasecmp($1, "no") == 0)
- $$ = 0;
- else {
- yyerror("invalid boolean value '%s'", $1);
- free($1);
- YYERROR;
- }
- free($1);
- }
- | ON { $$ = 1; }
- ;
-
-main : GOT_REPOS_PATH STRING {
- if ((gw_conf->got_repos_path = strdup($2)) == NULL)
- errx(1, "out of memory");
- }
- | GOT_MAX_REPOS NUMBER {
- if ($2 > 0)
- gw_conf->got_max_repos = $2;
- }
- | GOT_SITE_NAME STRING {
- if ((gw_conf->got_site_name = strdup($2)) == NULL)
- errx(1, "out of memory");
- }
- | GOT_SITE_OWNER STRING {
- if ((gw_conf->got_site_owner = strdup($2)) == NULL)
- errx(1, "out of memory");
- }
- | GOT_SITE_LINK STRING {
- if ((gw_conf->got_site_link = strdup($2)) == NULL)
- errx(1, "out of memory");
- }
- | GOT_LOGO STRING {
- if ((gw_conf->got_logo = strdup($2)) == NULL)
- errx(1, "out of memory");
- }
- | GOT_LOGO_URL STRING {
- if ((gw_conf->got_logo_url = strdup($2)) == NULL)
- errx(1, "out of memory");
- }
- | GOT_SHOW_SITE_OWNER boolean {
- gw_conf->got_show_site_owner = $2;
- }
- | GOT_SHOW_REPO_OWNER boolean {
- gw_conf->got_show_repo_owner = $2;
- }
- | GOT_SHOW_REPO_AGE boolean { gw_conf->got_show_repo_age = $2; }
- | GOT_SHOW_REPO_DESCRIPTION boolean {
- gw_conf->got_show_repo_description = $2;
- }
- | GOT_SHOW_REPO_CLONEURL boolean {
- gw_conf->got_show_repo_cloneurl = $2;
- }
- | GOT_MAX_REPOS_DISPLAY NUMBER {
- if ($2 > 0)
- gw_conf->got_max_repos_display = $2;
- }
- | GOT_MAX_COMMITS_DISPLAY NUMBER {
- if ($2 > 0)
- gw_conf->got_max_commits_display = $2;
- }
- ;
-
-%%
-
-struct keywords {
- const char *k_name;
- int k_val;
-};
-
-int
-yyerror(const char *fmt, ...)
-{
- va_list ap;
- char *msg = NULL;
- static char err_msg[512];
-
- file->errors++;
- va_start(ap, fmt);
- if (vasprintf(&msg, fmt, ap) == -1)
- errx(1, "yyerror vasprintf");
- va_end(ap);
- snprintf(err_msg, sizeof(err_msg), "%s:%d: %s", file->name,
- yylval.lineno, msg);
- gerror = got_error_from_errno2("parse_error", err_msg);
-
- free(msg);
- return (0);
-}
-
-int
-kw_cmp(const void *k, const void *e)
-{
- return (strcmp(k, ((const struct keywords *)e)->k_name));
-}
-
-int
-lookup(char *s)
-{
- /* this has to be sorted always */
- static const struct keywords keywords[] = {
- { "got_logo", GOT_LOGO },
- { "got_logo_url", GOT_LOGO_URL },
- { "got_max_commits_display", GOT_MAX_COMMITS_DISPLAY },
- { "got_max_repos", GOT_MAX_REPOS },
- { "got_max_repos_display", GOT_MAX_REPOS_DISPLAY },
- { "got_repos_path", GOT_REPOS_PATH },
- { "got_show_repo_age", GOT_SHOW_REPO_AGE },
- { "got_show_repo_cloneurl", GOT_SHOW_REPO_CLONEURL },
- { "got_show_repo_description", GOT_SHOW_REPO_DESCRIPTION },
- { "got_show_repo_owner", GOT_SHOW_REPO_OWNER },
- { "got_show_site_owner", GOT_SHOW_SITE_OWNER },
- { "got_site_link", GOT_SITE_LINK },
- { "got_site_name", GOT_SITE_NAME },
- { "got_site_owner", GOT_SITE_OWNER },
- };
- const struct keywords *p;
-
- p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
- sizeof(keywords[0]), kw_cmp);
-
- if (p)
- return (p->k_val);
- else
- return (STRING);
-}
-
-#define MAXPUSHBACK 128
-
-u_char *parsebuf;
-int parseindex;
-u_char pushback_buffer[MAXPUSHBACK];
-int pushback_index = 0;
-
-int
-lgetc(int quotec)
-{
- int c, next;
-
- if (parsebuf) {
- /* Read character from the parsebuffer instead of input. */
- if (parseindex >= 0) {
- c = parsebuf[parseindex++];
- if (c != '\0')
- return (c);
- parsebuf = NULL;
- } else
- parseindex++;
- }
-
- if (pushback_index)
- return (pushback_buffer[--pushback_index]);
-
- if (quotec) {
- if ((c = getc(file->stream)) == EOF) {
- yyerror("reached end of file while parsing "
- "quoted string");
- if (file == topfile || popfile() == EOF)
- return (EOF);
- return (quotec);
- }
- return (c);
- }
-
- while ((c = getc(file->stream)) == '\\') {
- next = getc(file->stream);
- if (next != '\n') {
- c = next;
- break;
- }
- yylval.lineno = file->lineno;
- file->lineno++;
- }
-
- while (c == EOF) {
- if (file == topfile || popfile() == EOF)
- return (EOF);
- c = getc(file->stream);
- }
- return (c);
-}
-
-int
-lungetc(int c)
-{
- if (c == EOF)
- return (EOF);
- if (parsebuf) {
- parseindex--;
- if (parseindex >= 0)
- return (c);
- }
- if (pushback_index < MAXPUSHBACK-1)
- return (pushback_buffer[pushback_index++] = c);
- else
- return (EOF);
-}
-
-int
-findeol(void)
-{
- int c;
-
- parsebuf = NULL;
-
- /* skip to either EOF or the first real EOL */
- while (1) {
- if (pushback_index)
- c = pushback_buffer[--pushback_index];
- else
- c = lgetc(0);
- if (c == '\n') {
- file->lineno++;
- break;
- }
- if (c == EOF)
- break;
- }
- return (ERROR);
-}
-
-int
-yylex(void)
-{
- u_char buf[8096];
- u_char *p;
- int quotec, next, c;
- int token;
-
- p = buf;
- while ((c = lgetc(0)) == ' ' || c == '\t')
- ; /* nothing */
-
- yylval.lineno = file->lineno;
- if (c == '#')
- while ((c = lgetc(0)) != '\n' && c != EOF)
- ; /* nothing */
-
- switch (c) {
- case '\'':
- case '"':
- quotec = c;
- while (1) {
- if ((c = lgetc(quotec)) == EOF)
- return (0);
- if (c == '\n') {
- file->lineno++;
- continue;
- } else if (c == '\\') {
- if ((next = lgetc(quotec)) == EOF)
- return (0);
- if (next == quotec || next == ' ' ||
- next == '\t')
- c = next;
- else if (next == '\n') {
- file->lineno++;
- continue;
- } else
- lungetc(next);
- } else if (c == quotec) {
- *p = '\0';
- break;
- } else if (c == '\0') {
- yyerror("syntax error");
- return (findeol());
- }
- if (p + 1 >= buf + sizeof(buf) - 1) {
- yyerror("string too long");
- return (findeol());
- }
- *p++ = c;
- }
- yylval.v.string = strdup(buf);
- if (yylval.v.string == NULL)
- errx(1, "yylex: strdup");
- return (STRING);
- }
-
-#define allowed_to_end_number(x) \
- (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
-
- if (c == '-' || isdigit(c)) {
- do {
- *p++ = c;
- if ((size_t)(p-buf) >= sizeof(buf)) {
- yyerror("string too long");
- return (findeol());
- }
- } while ((c = lgetc(0)) != EOF && isdigit(c));
- lungetc(c);
- if (p == buf + 1 && buf[0] == '-')
- goto nodigits;
- if (c == EOF || allowed_to_end_number(c)) {
- const char *errstr = NULL;
-
- *p = '\0';
- yylval.v.number = strtonum(buf, LLONG_MIN,
- LLONG_MAX, &errstr);
- if (errstr) {
- yyerror("\"%s\" invalid number: %s",
- buf, errstr);
- return (findeol());
- }
- return (NUMBER);
- } else {
-nodigits:
- while (p > buf + 1)
- lungetc(*--p);
- c = *--p;
- if (c == '-')
- return (c);
- }
- }
-
-#define allowed_in_string(x) \
- (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
- x != '{' && x != '}' && x != '<' && x != '>' && \
- x != '!' && x != '=' && x != '/' && x != '#' && \
- x != ','))
-
- if (isalnum(c) || c == ':' || c == '_' || c == '*') {
- do {
- *p++ = c;
- if ((size_t)(p-buf) >= sizeof(buf)) {
- yyerror("string too long");
- return (findeol());
- }
- } while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
- lungetc(c);
- *p = '\0';
- if ((token = lookup(buf)) == STRING)
- if ((yylval.v.string = strdup(buf)) == NULL)
- errx(1, "yylex: strdup");
- return (token);
- }
- if (c == '\n') {
- yylval.lineno = file->lineno;
- file->lineno++;
- }
- if (c == EOF)
- return (0);
- return (c);
-}
-
-struct file *
-pushfile(const char *name)
-{
- struct file *nfile;
-
- if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
- gerror = got_error(GOT_ERR_NO_SPACE);
- return (NULL);
- }
- if ((nfile->name = strdup(name)) == NULL) {
- gerror = got_error(GOT_ERR_NO_SPACE);
- free(nfile);
- return (NULL);
- }
- if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
- gerror = got_error_from_errno2("parse_conf", nfile->name);
- free(nfile->name);
- free(nfile);
- return (NULL);
- }
- nfile->lineno = 1;
- TAILQ_INSERT_TAIL(&files, nfile, entry);
- return (nfile);
-}
-
-int
-popfile(void)
-{
- struct file *prev;
-
- if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
- prev->errors += file->errors;
-
- TAILQ_REMOVE(&files, file, entry);
- fclose(file->stream);
- free(file->name);
- free(file);
- file = prev;
- return (file ? 0 : EOF);
-}
-
-const struct got_error*
-parse_conf(const char *filename, struct gotweb_conf *gconf)
-{
- static const struct got_error* error = NULL;
-
- gw_conf = gconf;
- if ((gw_conf->got_repos_path = strdup(D_GOTPATH)) == NULL)
- err(1, "strdup");
- if ((gw_conf->got_site_name = strdup(D_SITENAME)) == NULL)
- err(1, "strdup");
- if ((gw_conf->got_site_owner = strdup(D_SITEOWNER)) == NULL)
- err(1, "strdup");
- if ((gw_conf->got_site_link = strdup(D_SITELINK)) == NULL)
- err(1, "strdup");
- if ((gw_conf->got_logo = strdup(D_GOTLOGO)) == NULL)
- err(1, "strdup");
- if ((gw_conf->got_logo_url = strdup(D_GOTURL)) == NULL)
- err(1, "strdup");
- gw_conf->got_show_site_owner = D_SHOWSOWNER;
- gw_conf->got_show_repo_owner = D_SHOWROWNER;
- gw_conf->got_show_repo_age = D_SHOWAGE;
- gw_conf->got_show_repo_description = D_SHOWDESC;
- gw_conf->got_show_repo_cloneurl = D_SHOWURL;
- gw_conf->got_max_repos = D_MAXREPO;
- gw_conf->got_max_repos_display = D_MAXREPODISP;
- gw_conf->got_max_commits_display = D_MAXCOMMITDISP;
- if ((file = pushfile(filename)) == NULL) {
- goto done;
- }
- topfile = file;
-
- yyparse();
- popfile();
- if (gerror)
- error = gerror;
-done:
- return error;
-}
blob - 86074676dcb36a4dac9544e5dc676523abe57cab
blob + 2f83105c5db139494be4900c717b3e201ec6c3c0
--- include/got_config_parse.h
+++ include/got_config_parse.h
@@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <stdbool.h>
+
struct got_config_list_entry {
TAILQ_ENTRY(got_config_list_entry) entry;
const char *remote;
@@ -24,9 +26,59 @@ struct got_config_list_entry {
};
TAILQ_HEAD(got_config_list, got_config_list_entry);
+#define GOTWEB_CONF "/etc/gotweb.conf"
+#define GOTWEB_TMPL_DIR "/cgi-bin/gw_tmpl"
+#define GOTWEB "/cgi-bin/gotweb/gotweb"
+
+#define GOTWEB_GOT_DIR ".got"
+#define GOTWEB_GIT_DIR ".git"
+
+#define D_GOTPATH "/got/public"
+#define D_SITENAME "Gotweb"
+#define D_SITEOWNER "Got Owner"
+#define D_SITELINK "Repos"
+#define D_GOTLOGO "got.png"
+#define D_GOTURL "https://gameoftrees.org"
+
+#define D_SHOWROWNER true
+#define D_SHOWSOWNER true
+#define D_SHOWAGE true
+#define D_SHOWDESC true
+#define D_SHOWURL true
+#define D_MAXREPO 0
+#define D_MAXREPODISP 25
+#define D_MAXSLCOMMDISP 10
+#define D_MAXCOMMITDISP 25
+
+struct gotweb_config {
+ char *got_repos_path;
+ char *got_site_name;
+ char *got_site_owner;
+ char *got_site_link;
+ char *got_logo;
+ char *got_logo_url;
+
+ size_t got_max_repos;
+ size_t got_max_repos_display;
+ size_t got_max_commits_display;
+
+ bool got_show_site_owner;
+ bool got_show_repo_owner;
+ bool got_show_repo_age;
+ bool got_show_repo_description;
+ bool got_show_repo_cloneurl;
+};
+
/*
* Parse individual gotconfig repository files
* Load got_config_list_entry struct and insert to got_config_list TAILQ
*/
const struct got_error* got_config_parse_got_config(struct got_config_list **,
+ char *filename);
+
+/*
+ * Parse gotweb configuration
+ * Loads gotweb_config struct
+ */
+const struct got_error* got_config_parse_gotweb_config(struct gotweb_config **,
char *filename);
blob - dd1e0a6c7c9c05d864b33e126456dcef12734744
blob + dd48d92f485ecfb6ce6751735d2ea728c2920ea8
--- lib/parse.y
+++ lib/parse.y
@@ -37,6 +37,7 @@
#include <ifaddrs.h>
#include <imsg.h>
#include <limits.h>
+#include <stdbool.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
@@ -84,10 +85,13 @@ int symset(const char *, const char *, int);
char *symget(const char *);
const struct got_error* gerror = NULL;
-struct got_config_list_entry *gotconfig;
+
+struct got_config_list_entry *got_config;
struct got_config_list got_config_list;
-static const struct got_error* new_remote(struct got_config_list_entry **);
+static const struct got_error* new_remote(struct got_config_list_entry **);
+struct gotweb_config gw_conf;
+
typedef struct {
union {
int64_t number;
@@ -99,22 +103,102 @@ typedef struct {
%}
%token ERROR
+%token GOT_WWW_PATH GOT_MAX_REPOS GOT_SITE_NAME GOT_SITE_OWNER GOT_SITE_LINK
+%token GOT_LOGO GOT_LOGO_URL GOT_SHOW_REPO_OWNER GOT_SHOW_REPO_AGE
+%token GOT_SHOW_REPO_DESCRIPTION GOT_MAX_REPOS_DISPLAY GOT_REPOS_PATH
+%token GOT_MAX_COMMITS_DISPLAY ON GOT_SHOW_SITE_OWNER
+%token GOT_SHOW_REPO_CLONEURL
%token REMOTE REPOSITORY SERVER PROTOCOL USER
%token <v.string> STRING
%token <v.number> NUMBER
+%type <v.number> boolean
%%
grammar : /* empty */
| grammar '\n'
+ | grammar main '\n'
| grammar remote '\n'
;
+boolean : STRING {
+ if (strcasecmp($1, "true") == 0 ||
+ strcasecmp($1, "yes") == 0)
+ $$ = 1;
+ else if (strcasecmp($1, "false") == 0 ||
+ strcasecmp($1, "off") == 0 ||
+ strcasecmp($1, "no") == 0)
+ $$ = 0;
+ else {
+ yyerror("invalid boolean value '%s'", $1);
+ free($1);
+ YYERROR;
+ }
+ free($1);
+ }
+ | ON { $$ = 1; }
+ ;
+main : GOT_REPOS_PATH STRING {
+ gw_conf.got_repos_path = strdup($2);
+ if (gw_conf.got_repos_path== NULL)
+ errx(1, "out of memory");
+ }
+ | GOT_MAX_REPOS NUMBER {
+ if ($2 > 0)
+ gw_conf.got_max_repos = $2;
+ }
+ | GOT_SITE_NAME STRING {
+ gw_conf.got_site_name = strdup($2);
+ if (gw_conf.got_site_name == NULL)
+ errx(1, "out of memory");
+ }
+ | GOT_SITE_OWNER STRING {
+ gw_conf.got_site_owner = strdup($2);
+ if (gw_conf.got_site_owner == NULL)
+ errx(1, "out of memory");
+ }
+ | GOT_SITE_LINK STRING {
+ gw_conf.got_site_link = strdup($2);
+ if (gw_conf.got_site_link == NULL)
+ errx(1, "out of memory");
+ }
+ | GOT_LOGO STRING {
+ gw_conf.got_logo = strdup($2);
+ if (gw_conf.got_logo== NULL)
+ errx(1, "out of memory");
+ }
+ | GOT_LOGO_URL STRING {
+ gw_conf.got_logo_url = strdup($2);
+ if (gw_conf.got_logo_url== NULL)
+ errx(1, "out of memory");
+ }
+ | GOT_SHOW_SITE_OWNER boolean {
+ gw_conf.got_show_site_owner = $2;
+ }
+ | GOT_SHOW_REPO_OWNER boolean {
+ gw_conf.got_show_repo_owner = $2;
+ }
+ | GOT_SHOW_REPO_AGE boolean { gw_conf.got_show_repo_age = $2; }
+ | GOT_SHOW_REPO_DESCRIPTION boolean {
+ gw_conf.got_show_repo_description = $2;
+ }
+ | GOT_SHOW_REPO_CLONEURL boolean {
+ gw_conf.got_show_repo_cloneurl = $2;
+ }
+ | GOT_MAX_REPOS_DISPLAY NUMBER {
+ if ($2 > 0)
+ gw_conf.got_max_repos_display = $2;
+ }
+ | GOT_MAX_COMMITS_DISPLAY NUMBER {
+ if ($2 > 0)
+ gw_conf.got_max_commits_display = $2;
+ }
+ ;
remoteopts2 : remoteopts2 remoteopts1 nl
| remoteopts1 optnl
;
remoteopts1 : REPOSITORY STRING {
- gotconfig->repository = strdup($2);
- if (gotconfig->repository == NULL) {
+ got_config->repository = strdup($2);
+ if (got_config->repository == NULL) {
free($2);
yyerror("strdup");
YYERROR;
@@ -122,8 +206,8 @@ remoteopts1 : REPOSITORY STRING {
free($2);
}
| SERVER STRING {
- gotconfig->server = strdup($2);
- if (gotconfig->server == NULL) {
+ got_config->server = strdup($2);
+ if (got_config->server == NULL) {
free($2);
yyerror("strdup");
YYERROR;
@@ -131,8 +215,8 @@ remoteopts1 : REPOSITORY STRING {
free($2);
}
| PROTOCOL STRING {
- gotconfig->protocol = strdup($2);
- if (gotconfig->protocol == NULL) {
+ got_config->protocol = strdup($2);
+ if (got_config->protocol == NULL) {
free($2);
yyerror("strdup");
YYERROR;
@@ -140,8 +224,8 @@ remoteopts1 : REPOSITORY STRING {
free($2);
}
| USER STRING {
- gotconfig->user = strdup($2);
- if (gotconfig->user == NULL) {
+ got_config->user = strdup($2);
+ if (got_config->user == NULL) {
free($2);
yyerror("strdup");
YYERROR;
@@ -152,21 +236,21 @@ remoteopts1 : REPOSITORY STRING {
remote : REMOTE STRING {
static const struct got_error* error;
- error = new_remote(&gotconfig);
+ error = new_remote(&got_config);
if (error) {
free($2);
yyerror("%s", error->msg);
YYERROR;
}
- gotconfig->remote = strdup($2);
- if (gotconfig->remote == NULL) {
+ got_config->remote = strdup($2);
+ if (got_config->remote == NULL) {
free($2);
yyerror("strdup");
YYERROR;
}
free($2);
} '{' optnl remoteopts2 '}' {
- TAILQ_INSERT_TAIL(&got_config_list, gotconfig, entry);
+ TAILQ_INSERT_TAIL(&got_config_list, got_config, entry);
}
;
optnl : '\n' optnl
@@ -215,11 +299,25 @@ lookup(char *s)
{
/* This has to be sorted always. */
static const struct keywords keywords[] = {
- {"protocol", PROTOCOL},
- {"remote", REMOTE},
- {"repository", REPOSITORY},
- {"server", SERVER},
- {"user", USER},
+ { "got_logo", GOT_LOGO },
+ { "got_logo_url", GOT_LOGO_URL },
+ { "got_max_commits_display", GOT_MAX_COMMITS_DISPLAY },
+ { "got_max_repos", GOT_MAX_REPOS },
+ { "got_max_repos_display", GOT_MAX_REPOS_DISPLAY },
+ { "got_repos_path", GOT_REPOS_PATH },
+ { "got_show_repo_age", GOT_SHOW_REPO_AGE },
+ { "got_show_repo_cloneurl", GOT_SHOW_REPO_CLONEURL },
+ { "got_show_repo_description", GOT_SHOW_REPO_DESCRIPTION },
+ { "got_show_repo_owner", GOT_SHOW_REPO_OWNER },
+ { "got_show_site_owner", GOT_SHOW_SITE_OWNER },
+ { "got_site_link", GOT_SITE_LINK },
+ { "got_site_name", GOT_SITE_NAME },
+ { "got_site_owner", GOT_SITE_OWNER },
+ { "protocol", PROTOCOL },
+ { "remote", REMOTE },
+ { "repository", REPOSITORY },
+ { "server", SERVER },
+ { "user", USER },
};
const struct keywords *p;
@@ -526,10 +624,10 @@ pushfile(struct file **nfile, const char *name)
}
static const struct got_error*
-new_remote(struct got_config_list_entry **gotconfig) {
+new_remote(struct got_config_list_entry **got_config) {
const struct got_error* error = NULL;
- if (((*gotconfig) = calloc(1, sizeof(struct got_config_list_entry))) ==
+ if (((*got_config) = calloc(1, sizeof(struct got_config_list_entry))) ==
NULL)
error = got_error_from_errno("calloc");
return error;
@@ -578,6 +676,39 @@ got_config_parse_got_config(struct got_config_list **c
return gerror;
}
+const struct got_error*
+got_config_parse_gotweb_config(struct gotweb_config **gconf, char *filename)
+{
+ if ((gw_conf.got_repos_path = strdup(D_GOTPATH)) == NULL)
+ err(1, "strdup");
+ if ((gw_conf.got_site_name = strdup(D_SITENAME)) == NULL)
+ err(1, "strdup");
+ if ((gw_conf.got_site_owner = strdup(D_SITEOWNER)) == NULL)
+ err(1, "strdup");
+ if ((gw_conf.got_site_link = strdup(D_SITELINK)) == NULL)
+ err(1, "strdup");
+ if ((gw_conf.got_logo = strdup(D_GOTLOGO)) == NULL)
+ err(1, "strdup");
+ if ((gw_conf.got_logo_url = strdup(D_GOTURL)) == NULL)
+ err(1, "strdup");
+ gw_conf.got_show_site_owner = D_SHOWSOWNER;
+ gw_conf.got_show_repo_owner = D_SHOWROWNER;
+ gw_conf.got_show_repo_age = D_SHOWAGE;
+ gw_conf.got_show_repo_description = D_SHOWDESC;
+ gw_conf.got_show_repo_cloneurl = D_SHOWURL;
+ gw_conf.got_max_repos = D_MAXREPO;
+ gw_conf.got_max_repos_display = D_MAXREPODISP;
+ gw_conf.got_max_commits_display = D_MAXCOMMITDISP;
+ gerror = pushfile(&file, filename);
+ if (gerror)
+ return gerror;
+ topfile = file;
+
+ yyparse();
+ popfile();
+ *gconf = &gw_conf;
+ return gerror;
+}
int
symset(const char *nam, const char *val, int persist)
{
Make gotweb config parsing work with last diff