getopt shim, make format
diff --git a/Makefile.am b/Makefile.am
index 2de8237..866246a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,6 +14,7 @@ noinst_HEADERS = include/cm.h \
include/libsais.h \
include/lzp.h \
include/rle.h
+ include/getopt-shim.h
lib_LTLIBRARIES = libbzip3.la
libbzip3_la_SOURCES = src/cm.c \
diff --git a/configure.ac b/configure.ac
index ca050bc..9d77c00 100644
--- a/configure.ac
+++ b/configure.ac
@@ -16,6 +16,9 @@ LT_INIT
PKG_PROG_PKG_CONFIG
PKG_INSTALLDIR
+AC_CHECK_HEADERS([getopt.h])
+AC_CHECK_FUNCS([getopt_long])
+
AC_ARG_WITH([pthread],
AS_HELP_STRING([--without-pthread], [Disable use of pthread library]))
AM_CONDITIONAL([WITH_PTHREAD], [test x"$with_pthread" != xno])
diff --git a/include/getopt-shim.h b/include/getopt-shim.h
new file mode 100644
index 0000000..fde2108
--- /dev/null
+++ b/include/getopt-shim.h
@@ -0,0 +1,253 @@
+/*
+ Copyright 2005-2014 Rich Felker, et al.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef _GETOPT_H
+#define _GETOPT_H
+
+int getopt(int, char * const [], const char *);
+extern char *optarg;
+extern int optind, opterr, optopt, optreset;
+
+struct option {
+ const char *name;
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+int getopt_long(int, char *const *, const char *, const struct option *, int *);
+int getopt_long_only(int, char *const *, const char *, const struct option *, int *);
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+char *optarg;
+int optind=1, opterr=1, optopt, __optpos, optreset=0;
+
+#define optpos __optpos
+
+static void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
+{
+ FILE *f = stderr;
+ flockfile(f);
+ fputs(a, f)>=0
+ && fwrite(b, strlen(b), 1, f)
+ && fwrite(c, 1, l, f)==l
+ && putc('\n', f);
+ funlockfile(f);
+}
+
+int getopt(int argc, char * const argv[], const char *optstring)
+{
+ int i, c, d;
+ int k, l;
+ char *optchar;
+
+ if (!optind || optreset) {
+ optreset = 0;
+ __optpos = 0;
+ optind = 1;
+ }
+
+ if (optind >= argc || !argv[optind])
+ return -1;
+
+ if (argv[optind][0] != '-') {
+ if (optstring[0] == '-') {
+ optarg = argv[optind++];
+ return 1;
+ }
+ return -1;
+ }
+
+ if (!argv[optind][1])
+ return -1;
+
+ if (argv[optind][1] == '-' && !argv[optind][2])
+ return optind++, -1;
+
+ if (!optpos) optpos++;
+ c = argv[optind][optpos], k = 1;
+ optchar = argv[optind]+optpos;
+ optopt = c;
+ optpos += k;
+
+ if (!argv[optind][optpos]) {
+ optind++;
+ optpos = 0;
+ }
+
+ if (optstring[0] == '-' || optstring[0] == '+')
+ optstring++;
+
+ i = 0;
+ d = 0;
+ do {
+ d = optstring[i], l = 1;
+ if (l>0) i+=l; else i++;
+ } while (l && d != c);
+
+ if (d != c) {
+ if (optstring[0] != ':' && opterr)
+ __getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
+ return '?';
+ }
+ if (optstring[i] == ':') {
+ if (optstring[i+1] == ':') optarg = 0;
+ else if (optind >= argc) {
+ if (optstring[0] == ':') return ':';
+ if (opterr) __getopt_msg(argv[0],
+ ": option requires an argument: ",
+ optchar, k);
+ return '?';
+ }
+ if (optstring[i+1] != ':' || optpos) {
+ optarg = argv[optind++] + optpos;
+ optpos = 0;
+ }
+ }
+ return c;
+}
+
+static void permute(char *const *argv, int dest, int src)
+{
+ char **av = (char **)argv;
+ char *tmp = av[src];
+ int i;
+ for (i=src; i>dest; i--)
+ av[i] = av[i-1];
+ av[dest] = tmp;
+}
+
+static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
+{
+ optarg = 0;
+ if (longopts && argv[optind][0] == '-' &&
+ ((longonly && argv[optind][1] && argv[optind][1] != '-') ||
+ (argv[optind][1] == '-' && argv[optind][2])))
+ {
+ int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':';
+ int i, cnt, match;
+ char *opt;
+ for (cnt=i=0; longopts[i].name; i++) {
+ const char *name = longopts[i].name;
+ opt = argv[optind]+1;
+ if (*opt == '-') opt++;
+ for (; *name && *name == *opt; name++, opt++);
+ if (*opt && *opt != '=') continue;
+ match = i;
+ if (!*name) {
+ cnt = 1;
+ break;
+ }
+ cnt++;
+ }
+ if (cnt==1) {
+ i = match;
+ optind++;
+ optopt = longopts[i].val;
+ if (*opt == '=') {
+ if (!longopts[i].has_arg) {
+ if (colon || !opterr)
+ return '?';
+ __getopt_msg(argv[0],
+ ": option does not take an argument: ",
+ longopts[i].name,
+ strlen(longopts[i].name));
+ return '?';
+ }
+ optarg = opt+1;
+ } else if (longopts[i].has_arg == required_argument) {
+ if (!(optarg = argv[optind])) {
+ if (colon) return ':';
+ if (!opterr) return '?';
+ __getopt_msg(argv[0],
+ ": option requires an argument: ",
+ longopts[i].name,
+ strlen(longopts[i].name));
+ return '?';
+ }
+ optind++;
+ }
+ if (idx) *idx = i;
+ if (longopts[i].flag) {
+ *longopts[i].flag = longopts[i].val;
+ return 0;
+ }
+ return longopts[i].val;
+ }
+ if (argv[optind][1] == '-') {
+ if (!colon && opterr)
+ __getopt_msg(argv[0], cnt ?
+ ": option is ambiguous: " :
+ ": unrecognized option: ",
+ argv[optind]+2,
+ strlen(argv[optind]+2));
+ optind++;
+ return '?';
+ }
+ }
+ return getopt(argc, argv, optstring);
+}
+
+static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
+{
+ int ret, skipped, resumed;
+ if (!optind || optreset) {
+ optreset = 0;
+ __optpos = 0;
+ optind = 1;
+ }
+ if (optind >= argc || !argv[optind]) return -1;
+ skipped = optind;
+ if (optstring[0] != '+' && optstring[0] != '-') {
+ int i;
+ for (i=optind; ; i++) {
+ if (i >= argc || !argv[i]) return -1;
+ if (argv[i][0] == '-' && argv[i][1]) break;
+ }
+ optind = i;
+ }
+ resumed = optind;
+ ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly);
+ if (resumed > skipped) {
+ int i, cnt = optind-resumed;
+ for (i=0; i<cnt; i++)
+ permute(argv, skipped, optind-1);
+ optind = skipped + cnt;
+ }
+ return ret;
+}
+
+int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
+{
+ return __getopt_long(argc, argv, optstring, longopts, idx, 0);
+}
+
+int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
+{
+ return __getopt_long(argc, argv, optstring, longopts, idx, 1);
+}
+
+#endif
diff --git a/src/cm.c b/src/cm.c
index d669922..8a30874 100644
--- a/src/cm.c
+++ b/src/cm.c
@@ -1,5 +1,6 @@
#include "cm.h"
+
#include "common.h"
#if defined(__has_builtin)
diff --git a/src/crc32.c b/src/crc32.c
index d455a44..851cd6c 100644
--- a/src/crc32.c
+++ b/src/crc32.c
@@ -18,6 +18,7 @@
*/
#include "crc32.h"
+
#include "common.h"
static const u32 crc32Table[256] = {
diff --git a/src/libsais.c b/src/libsais.c
index 04d45e8..5587f28 100644
--- a/src/libsais.c
+++ b/src/libsais.c
@@ -22,7 +22,6 @@ Please see the file LICENSE for full copyright information.
--*/
#include "libsais.h"
-#include "common.h"
#include <limits.h>
#include <stddef.h>
@@ -30,6 +29,8 @@ Please see the file LICENSE for full copyright information.
#include <stdlib.h>
#include <string.h>
+#include "common.h"
+
#define UNUSED(_x) (void)(_x)
typedef s32 sa_sint_t;
diff --git a/src/main.c b/src/main.c
index 6b5bf32..82d7a82 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,7 +25,13 @@
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
-#include <getopt.h>
+
+#ifdef HAVE_GETOPT_LONG
+ #include <getopt.h>
+#else
+ #include "getopt-shim.h"
+#endif
+
#if defined __MSVCRT__
#include <fcntl.h>
#include <io.h>
@@ -39,11 +45,11 @@
#define MODE_TEST 2
static void version() {
- fprintf(stdout,
- "bzip3 "VERSION"\n"
- "Copyright (C) by Kamila Szewczyk, 2022.\n"
- "License: GNU Lesser GPL version 3 <https://www.gnu.org/licenses/lgpl-3.0.en.html>\n");
- }
+ fprintf(stdout, "bzip3 " VERSION
+ "\n"
+ "Copyright (C) by Kamila Szewczyk, 2022.\n"
+ "License: GNU Lesser GPL version 3 <https://www.gnu.org/licenses/lgpl-3.0.en.html>\n");
+}
static void help() {
fprintf(stdout,
@@ -99,27 +105,25 @@ int main(int argc, char * argv[]) {
const char * short_options = "b:cdefhtV";
#endif
- static struct option long_options[] = {
- {"encode", no_argument, 0, 'e'},
- {"decode", no_argument, 0, 'd'},
- {"test", no_argument, 0, 't'},
- {"stdout", no_argument, 0, 'c'},
- {"force", no_argument, 0, 'f'},
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'V'},
- {"block", required_argument, 0, 'b'},
+ static struct option long_options[] = { { "encode", no_argument, 0, 'e' },
+ { "decode", no_argument, 0, 'd' },
+ { "test", no_argument, 0, 't' },
+ { "stdout", no_argument, 0, 'c' },
+ { "force", no_argument, 0, 'f' },
+ { "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'V' },
+ { "block", required_argument, 0, 'b' },
#ifdef PTHREAD
- {"jobs", required_argument, 0, 'j'},
+ { "jobs", required_argument, 0, 'j' },
#endif
- {0, 0, 0, 0 }
- };
+ { 0, 0, 0, 0 } };
- while(1) {
+ while (1) {
int option_index = 0;
int c = getopt_long(argc, argv, short_options, long_options, &option_index);
if (c == -1) break;
- switch(c) {
+ switch (c) {
case '?':
fprintf(stderr, "Try 'bzip3 --help' for more information.\n");
return 1;
@@ -192,10 +196,10 @@ int main(int argc, char * argv[]) {
input = f1;
else {
if (mode == MODE_ENCODE) {
- if(f2 == NULL) {
+ if (f2 == NULL) {
// encode from f1?
input = f1;
- if(force_stdstreams)
+ if (force_stdstreams)
output = NULL;
else {
output = (char *)malloc(strlen(f1) + 5);
@@ -204,18 +208,19 @@ int main(int argc, char * argv[]) {
}
} else {
// encode from f1 to f2.
- input = f1; output = f2;
+ input = f1;
+ output = f2;
}
- } else if(mode == MODE_DECODE) {
- if(f2 == NULL) {
+ } else if (mode == MODE_DECODE) {
+ if (f2 == NULL) {
// decode from f1 to stdout.
input = f1;
- if(force_stdstreams)
+ if (force_stdstreams)
output = NULL;
else {
output = (char *)malloc(strlen(f1) + 1);
strcpy(output, f1);
- if(strlen(output) > 4 && !strcmp(output + strlen(output) - 4, ".bz3"))
+ if (strlen(output) > 4 && !strcmp(output + strlen(output) - 4, ".bz3"))
output[strlen(output) - 4] = 0;
else {
fprintf(stderr, "Warning: file %s has an unknown extension, skipping.\n", f1);
@@ -224,11 +229,12 @@ int main(int argc, char * argv[]) {
}
} else {
// decode from f1 to f2.
- input = f1; output = f2;
+ input = f1;
+ output = f2;
}
}
}
-
+
FILE *input_des = NULL, *output_des = NULL;
if (input != NULL) {
diff --git a/src/rle.c b/src/rle.c
index ea1cfd1..87271fc 100644
--- a/src/rle.c
+++ b/src/rle.c
@@ -18,6 +18,7 @@
*/
#include "rle.h"
+
#include "common.h"
s32 mrlec(u8 * in, s32 inlen, u8 * out) {
