commit d429e285091db54f4b2d2bea157bd28a28355a93
parent dae746f33d9c8ad926eff935370e0f34ee91ac50
Author: Chris Bracken <chris@bracken.jp>
Date: Fri, 20 Feb 2026 19:05:05 +0900
options: migrate to getopt
Diffstat:
| M | src/gout.c | | | 94 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
| M | src/gout_index.c | | | 45 | ++++++++++++++++++++++++++++----------------- |
2 files changed, 71 insertions(+), 68 deletions(-)
diff --git a/src/gout.c b/src/gout.c
@@ -4,6 +4,7 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include "git/commit.h"
#include "git/file.h"
@@ -27,62 +28,53 @@ GoutOptions* gout_options_create(int argc, const char* argv[]) {
.baseurl = "",
.writer_type = kRepoWriterTypeHtml,
};
- for (int i = 1; i < argc; i++) {
- if (argv[i][0] != '-') {
- // Cannot specify more than one repo directory.
- if (options.repodir) {
- return NULL;
- }
- options.repodir = argv[i];
- } else if (argv[i][1] == 'c') {
- // Cache the entries of the log page up to the point of the last commit.
- // The cachefile will store the last commit id and the entries in the
- // HTML table. It is up to the user to make sure the state of the
- // cachefile is in sync with the history of the repository.
-
- // Mutually exclusive with -l.
- if (options.log_commit_limit > 0) {
- return NULL;
- }
- // Requires cachefile path argument.
- if (i + 1 >= argc) {
- return NULL;
- }
- options.cachefile_path = argv[++i];
- } else if (argv[i][1] == 'l') {
- // Write a maximum number of commits to the log.html file only. However
- // the commit files are written as usual.
-
- // Mutually exclusive with -c option.
- if (options.cachefile_path) {
- return NULL;
- }
- // Requires log commits argument.
- if (i + 1 >= argc) {
- return NULL;
- }
- errno = 0;
- char* p;
- options.log_commit_limit = strtoll(argv[++i], &p, 10);
- if (!argv[i][0] || *p || options.log_commit_limit <= 0 || errno) {
- return NULL;
- }
- } else if (argv[i][1] == 'u') {
- // Requires log commits argument.
- if (i + 1 >= argc) {
+
+ int ch;
+ optind = 1;
+ opterr = 0;
+ while ((ch = getopt(argc, (char* const*)argv, "c:l:u:HG")) != -1) {
+ switch (ch) {
+ case 'c':
+ // Mutually exclusive with -l.
+ if (options.log_commit_limit > 0) {
+ return NULL;
+ }
+ options.cachefile_path = optarg;
+ break;
+ case 'l':
+ // Mutually exclusive with -c.
+ if (options.cachefile_path) {
+ return NULL;
+ }
+ errno = 0;
+ char* p;
+ options.log_commit_limit = strtoll(optarg, &p, 10);
+ if (!optarg[0] || *p || options.log_commit_limit <= 0 || errno) {
+ return NULL;
+ }
+ break;
+ case 'u':
+ options.baseurl = optarg;
+ break;
+ case 'H':
+ options.writer_type = kRepoWriterTypeHtml;
+ break;
+ case 'G':
+ options.writer_type = kRepoWriterTypeGopher;
+ break;
+ default:
return NULL;
- }
- options.baseurl = argv[++i];
- } else if (argv[i][1] == 'H') {
- options.writer_type = kRepoWriterTypeHtml;
- } else if (argv[i][1] == 'G') {
- options.writer_type = kRepoWriterTypeGopher;
}
}
- // Must specify at least one repo directory.
- if (!options.repodir) {
+ argc -= optind;
+ argv += optind;
+
+ // Must specify exactly one repo directory.
+ if (argc != 1) {
return NULL;
}
+ options.repodir = argv[0];
+
GoutOptions* options_out = ecalloc(1, sizeof(GoutOptions));
*options_out = options;
return options_out;
diff --git a/src/gout_index.c b/src/gout_index.c
@@ -4,6 +4,7 @@
#include <err.h>
#include <stddef.h>
#include <stdlib.h>
+#include <unistd.h>
#include "git/git.h"
#include "security.h"
@@ -21,26 +22,36 @@ GoutIndexOptions* gout_index_options_create(int argc, const char* argv[]) {
.me_url = NULL,
.writer_type = kIndexWriterTypeHtml,
};
- for (int i = 1; i < argc; i++) {
- if (argv[i][0] != '-') {
- options.repo_dirs = reallocarray(
- options.repo_dirs, options.repo_dir_count + 1, sizeof(char*));
- if (!options.repo_dirs) {
- err(1, "reallocarray");
- }
- options.repo_dirs[options.repo_dir_count++] = argv[i];
- } else if (argv[i][1] == 'm') {
- // Requires 'me' URL argument.
- if (i + 1 >= argc) {
+
+ int ch;
+ optind = 1;
+ opterr = 0;
+ while ((ch = getopt(argc, (char* const*)argv, "m:HG")) != -1) {
+ switch (ch) {
+ case 'm':
+ options.me_url = optarg;
+ break;
+ case 'H':
+ options.writer_type = kIndexWriterTypeHtml;
+ break;
+ case 'G':
+ options.writer_type = kIndexWriterTypeGopher;
+ break;
+ default:
return NULL;
- }
- options.me_url = argv[++i];
- } else if (argv[i][1] == 'H') {
- options.writer_type = kIndexWriterTypeHtml;
- } else if (argv[i][1] == 'G') {
- options.writer_type = kIndexWriterTypeGopher;
}
}
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 0) {
+ options.repo_dirs = ecalloc(argc, sizeof(char*));
+ for (int i = 0; i < argc; i++) {
+ options.repo_dirs[i] = argv[i];
+ }
+ options.repo_dir_count = argc;
+ }
+
GoutIndexOptions* options_out = ecalloc(1, sizeof(GoutIndexOptions));
*options_out = options;
return options_out;