123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- #include <err.h>
- #include <stdio.h>
- #include <stdint.h>
- #include <string.h>
- #include <stdlib.h>
- #include <interface99.h>
- #include "arg.h"
- #include "util.h"
- #include "archives.h"
- char* argv0; /* for arg.h */
- /* clang-format off */
- static const char usage[] =
- "[OPTIONS] -- <subcmd> <args...>\n\n"
- "OPTIONS:\n"
- "\t-v verbose\n"
- "\t-V print version\n"
- "\t-h show this help\n"
- "\t-n dry run\n"
- "\t-e <ext:str> set custom extension\n"
- "\t-o <dir:path> set output directory (default: .)\n"
- "\t-f <file:path> set output file\n"
- "\t (only for {de,}compression of single files)\n"
- "\n"
- "\t-T <threads:int> set number of threads\n"
- "\t (for {de,}compressors that supports it)\n"
- "\t-M <limit:str> set memory limit\n"
- "\t (for {de,}compressors that supports it)\n"
- "\n"
- "<subcmds>:\n"
- "\tc <archive> <file...> create <archive> with files <file...>\n"
- "\tx <archive> extract files from <archive>\n"
- "\tl <archive> list contents of <archive>"
- ;
- /* clang-format on */
- static inline _Noreturn void
- die_usage(const char* msg)
- {
- errx(1, "%s\n\n%s", msg, usage);
- }
- /*
- * add -D_clang_check__ to you code checker to suppres errors
- * vim with neomake:
- * ```vim
- * let g:neomake_c_clangtidy_args = ['%t', '--', '-D_clang_check__']
- * let g:neomake_c_clang_args = neomake#makers#ft#c#clang().args + [
- * \ '-D_clang_check__']
- * ```
- */
- #ifndef VERSION
- # ifndef _clang_check__
- # error VERSION not defined
- # else
- # define VERSION "<_clang_check__>"
- # endif
- #endif /* VERSION */
- int
- main(int argc, char* argv[])
- {
- char action, *archive, *ext = NULL;
- struct Config cfg = {
- .dry_run = 0,
- .verbose = 0,
- .out_dir = ".",
- .out_file = NULL,
- .custom_ext = NULL,
- .threads = NULL,
- .memory_limit = NULL,
- };
- ARGBEGIN
- {
- case 'h':
- errx(0, "%s", usage);
- case 'V':
- errx(0, "%s", VERSION);
- case 'n':
- cfg.dry_run = !0;
- break;
- case 'v':
- cfg.verbose = !0;
- break;
- case 'o':
- cfg.out_dir = EARGF(die_usage("specify output directory"));
- break;
- case 'f':
- cfg.out_file = EARGF(die_usage("specify custom file name"));
- break;
- case 'e':
- ext = EARGF(die_usage("specify custom extension"));
- break;
- case 'T':
- cfg.threads = EARGF(die_usage("specify threads count"));
- break;
- case 'M':
- cfg.memory_limit = EARGF(die_usage("specify memory limit"));
- break;
- default:
- warnx("invalid argument: -%c", ARGC());
- }
- ARGEND;
- size_t custom_ext_size =
- ext ? (STR_SIZE("archive.") + strlen(ext) + 1) : 0;
- char custom_ext_buf[custom_ext_size
- + (!custom_ext_size /* to not be zero-size */)];
- if (!!custom_ext_size) {
- snprintf(custom_ext_buf, custom_ext_size, "archive.%s", ext);
- cfg.custom_ext = custom_ext_buf;
- }
- if (!*argv) die_usage("specify action");
- if (!**argv || !!(*argv)[1]) die_usage("invalid action");
- action = **(argv++);
- if (!*argv) die_usage("specify archive file");
- archive = *(argv++);
- cfg.files = argv;
- cfg.files_count = argc - 2;
- cfg.custom_ext = OR(cfg.custom_ext, archive);
- for (size_t i = 0; i < LEN(archives); i++) {
- if (!!VCALL_SUPER(archives[i], Match, match, cfg.custom_ext)) {
- int (*func)(void*, char* const);
- switch (action) {
- case 'l':
- func = archives[i].vptr->List->list;
- break;
- case 'x':
- func = archives[i].vptr->Extract->extract;
- break;
- case 'c':
- if (cfg.files_count < 1)
- die_usage(
- "provide some files to create "
- "archive");
- func = archives[i].vptr->Create->create;
- break;
- default:
- errx(1,
- "invalid action: %c\n\n%s",
- action,
- usage);
- }
- return func(&cfg, archive);
- }
- }
- errx(1, "no awailiable extractros found for '%s'", cfg.custom_ext);
- }
|