frontend: add helper macros for getopt()

This commit is contained in:
CismonX 2025-03-13 07:55:35 +08:00
parent bd343ddf4b
commit 68aafe3d8d
No known key found for this signature in database
GPG key ID: 3094873E29A482FB
4 changed files with 52 additions and 79 deletions

View file

@ -25,13 +25,28 @@
#include <stdlib.h> #include <stdlib.h>
#include "backend.h" #include <unistd.h>
#include "defs.h"
#include "fsck_handler.h"
#define getopt_foreach(argc, argv, optstr) \ #include "backend.h"
for (int opt_; -1 != (opt_ = getopt(argc, argv, optstr)); ) \ #include "fsck_handler.h"
switch (opt_) #include "xstd.h"
#define OPT_START(argc, argv, optstr) \
for (int opt_; -1 != (opt_ = getopt(argc, argv, ":" optstr)); ) { \
switch (opt_) {
#define OPT_OPT(opt) case opt:
#define OPT_NOVAL \
case ':': \
log_printf("no value provided for option '-%c'", optopt); \
return -1;
#define OPT_END \
default: \
log_printf("invalid option '-%c'", optopt); \
return -1; \
} \
} \
argc -= optind; \
argv += optind;
#define SUBOPT_START(opts) \ #define SUBOPT_START(opts) \
while (optarg[0] != '\0') { \ while (optarg[0] != '\0') { \

View file

@ -28,8 +28,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#ifdef BOOKMARKFS_INTERACTIVE_FSCK #ifdef BOOKMARKFS_INTERACTIVE_FSCK
# include <readline/history.h> # include <readline/history.h>
# include <readline/readline.h> # include <readline/readline.h>
@ -382,8 +380,8 @@ parse_opts (
BOOKMARKFS_OPT(END_, NULL), BOOKMARKFS_OPT(END_, NULL),
}; };
getopt_foreach(argc, argv, ":o:iRhV") { OPT_START(argc, argv, "o:iRhV")
case 'o': OPT_OPT('o') {
SUBOPT_START(opts) SUBOPT_START(opts)
SUBOPT_OPT(BOOKMARKFS_OPT_BACKEND) SUBOPT_HAS_VAL { SUBOPT_OPT(BOOKMARKFS_OPT_BACKEND) SUBOPT_HAS_VAL {
char const *name = SUBOPT_VAL; char const *name = SUBOPT_VAL;
@ -438,8 +436,8 @@ parse_opts (
} }
} }
SUBOPT_END SUBOPT_END
}
case 'i': OPT_OPT('i') {
#ifdef BOOKMARKFS_INTERACTIVE_FSCK #ifdef BOOKMARKFS_INTERACTIVE_FSCK
info->flags.interactive = 1; info->flags.interactive = 1;
break; break;
@ -448,34 +446,24 @@ parse_opts (
"interactive fsck is not enabled on this build"); "interactive fsck is not enabled on this build");
return -1; return -1;
#endif #endif
}
case 'R': OPT_OPT('R') {
info->flags.recursive = 1; info->flags.recursive = 1;
break; break;
}
case 'h': OPT_OPT('h') {
info->flags.print_help = 1; info->flags.print_help = 1;
info->flags.no_fsck = 1; info->flags.no_fsck = 1;
return 0; return 0;
}
case 'V': OPT_OPT('V') {
info->flags.print_version = 1; info->flags.print_version = 1;
info->flags.no_fsck = 1; info->flags.no_fsck = 1;
return 0; return 0;
case ':':
log_printf("no value provided for option '-%c'", optopt);
return -1;
case '?':
log_printf("invalid option '-%c'", optopt);
return -1;
default:
unreachable();
} }
OPT_NOVAL
OPT_END
argc -= optind;
if (argc != 1) { if (argc != 1) {
if (argc < 1) { if (argc < 1) {
log_puts("pathname must be specified"); log_puts("pathname must be specified");
@ -484,8 +472,6 @@ parse_opts (
} }
return -1; return -1;
} }
argv += optind;
info->path = argv[0]; info->path = argv[0];
return 0; return 0;
} }

View file

@ -27,8 +27,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include "frontend_util.h" #include "frontend_util.h"
#include "macros.h" #include "macros.h"
#include "version.h" #include "version.h"
@ -76,8 +74,8 @@ parse_opts (
BOOKMARKFS_OPT(END_, NULL), BOOKMARKFS_OPT(END_, NULL),
}; };
getopt_foreach(argc, argv, ":o:hV") { OPT_START(argc, argv, "o:hV")
case 'o': OPT_OPT('o') {
SUBOPT_START(opts) SUBOPT_START(opts)
SUBOPT_OPT(BOOKMARKFS_OPT_BACKEND) SUBOPT_HAS_VAL { SUBOPT_OPT(BOOKMARKFS_OPT_BACKEND) SUBOPT_HAS_VAL {
char const *name = SUBOPT_VAL; char const *name = SUBOPT_VAL;
@ -99,45 +97,33 @@ parse_opts (
} }
} }
SUBOPT_END SUBOPT_END
}
case 'h': OPT_OPT('h') {
ctx->flags.no_mkfs = 1; ctx->flags.no_mkfs = 1;
ctx->flags.print_help = 1; ctx->flags.print_help = 1;
return 0; return 0;
}
case 'V': OPT_OPT('V') {
ctx->flags.no_mkfs = 1; ctx->flags.no_mkfs = 1;
ctx->flags.print_version = 1; ctx->flags.print_version = 1;
return 0; return 0;
case ':':
log_printf("no value provided for option '-%c'", optopt);
return -1;
case '?':
log_printf("invalid option '-%c'", optopt);
return -1;
default:
unreachable();
} }
OPT_NOVAL
OPT_END
if (ctx->backend_name == NULL) { if (ctx->backend_name == NULL) {
log_puts("backend not specified"); log_puts("backend not specified");
return -1; return -1;
} }
argc -= optind;
if (argc != 1) { if (argc != 1) {
if (argc == 0) { if (argc == 0) {
log_puts("bookmark filepath must be specified"); log_puts("destination must be specified");
} else { } else {
log_puts("too many arguments"); log_puts("too many arguments");
} }
return -1; return -1;
} }
argv += optind;
ctx->backend_conf.store_path = argv[0]; ctx->backend_conf.store_path = argv[0];
return 0; return 0;
} }

View file

@ -28,8 +28,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "frontend_util.h" #include "frontend_util.h"
#include "fs_ops.h" #include "fs_ops.h"
#include "lib.h" #include "lib.h"
@ -415,8 +413,8 @@ parse_opts (
(result) = num_; \ (result) = num_; \
} while (0) } while (0)
getopt_foreach(argc, argv, ":o:FhV") { OPT_START(argc, argv, "o:FhV")
case 'o': OPT_OPT('o') {
SUBOPT_START(opts) SUBOPT_START(opts)
SUBOPT_OPT(BOOKMARKFS_OPT_ACCMODE) SUBOPT_HAS_VAL { SUBOPT_OPT(BOOKMARKFS_OPT_ACCMODE) SUBOPT_HAS_VAL {
SUBOPT_PARSE_NUM(0, 0777, info->fs_flags.accmode); SUBOPT_PARSE_NUM(0, 0777, info->fs_flags.accmode);
@ -469,39 +467,29 @@ parse_opts (
debug_printf("option '-o %s' ignored", SUBOPT_STR); debug_printf("option '-o %s' ignored", SUBOPT_STR);
} }
SUBOPT_END SUBOPT_END
}
case 'F': OPT_OPT('F') {
info->flags.is_foreground = 1; info->flags.is_foreground = 1;
break; break;
}
case 'h': OPT_OPT('h') {
info->flags.print_help = 1; info->flags.print_help = 1;
info->flags.no_mount = 1; info->flags.no_mount = 1;
return 0; return 0;
}
case 'V': OPT_OPT('V') {
info->flags.print_version = 1; info->flags.print_version = 1;
info->flags.no_mount = 1; info->flags.no_mount = 1;
return 0; return 0;
case ':':
log_printf("no value provided for option '-%c'", optopt);
return -1;
case '?':
log_printf("invalid option '-%c'", optopt);
return -1;
default:
unreachable();
} }
OPT_NOVAL
OPT_END
if (info->backend_name == NULL) { if (info->backend_name == NULL) {
log_puts("backend not specified"); log_puts("backend not specified");
return -1; return -1;
} }
argc -= optind;
if (argc != 2) { if (argc != 2) {
if (argc < 2) { if (argc < 2) {
log_puts("mount source and target must be specified"); log_puts("mount source and target must be specified");
@ -510,8 +498,6 @@ parse_opts (
} }
return -1; return -1;
} }
argv += optind;
info->backend_conf.store_path = argv[0]; info->backend_conf.store_path = argv[0];
info->mount_target = argv[1]; info->mount_target = argv[1];
return 0; return 0;