Commits

Michał Górny  committed 5785bba

Simple getopt() wrapper with automagic generation of optstring.
Ability to compile without getopt (and without optparsing).

  • Participants
  • Parent commits ee83b59

Comments (0)

Files changed (4)

 MIRAGE_LIBS = $$(pkg-config --libs-only-l libmirage)
 
 PROG = mirage2iso
-OBJS = mirage-wrapper.o
+OBJS = mirage-getopt.o mirage-wrapper.o
 
 DESTDIR = 
 PREFIX = /usr/local
 $(PROG): $(PROG).c $(OBJS)
 	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(MIRAGE_LDFLAGS) -o $@ $< $(OBJS) $(MIRAGE_LIBS)
 
-.c.o:
+mirage-wrapper.o: mirage-wrapper.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) $(MIRAGE_CPPFLAGS) -c -o $@ $<
 
+.c.o:
+	$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
+
 clean:
 	rm -f $(PROG) $(OBJS)
 

File mirage-getopt.c

+/* mirage2iso; getopt wrapper
+ * (c) 2009 Michał Górny
+ * released under 3-clause BSD license
+ */
+
+#include "mirage-features.h"
+
+#ifndef NO_GETOPT_LONG
+
+#define _GNU_SOURCE 1
+#include <stdlib.h>
+#include <getopt.h>
+
+const int mirage_getopt(int argc, char* const argv[], const struct option *longopts) {
+	const struct option *op;
+	int len = 1; /* trailing \0 */
+
+	for (op = longopts; op->name; op++) {
+		if (op->val) {
+			len++;
+			if (op->has_arg != no_argument)
+				len++;
+		}
+	}
+
+	char buf[len];
+	char* bufptr = buf;
+
+	for (op = longopts; op->name; op++) {
+		if (op->val) {
+			*(bufptr++) = op->val;
+			if (op->has_arg == required_argument)
+				*(bufptr++) = ':';
+		}
+	}
+	*bufptr = 0;
+
+	return getopt_long(argc, argv, buf, longopts, NULL);
+}
+
+#else
+
+#define _ISOC99_SOURCE 1
+#include "mirage-getopt.h"
+
+#warning "Currently NO_GETOPT_LONG implies *no* argument parsing, sorry."
+
+const int mirage_getopt(int argc, char* const argv[], const struct option *longopts) {
+	optind = 1;
+
+	return -1;
+}
+
+#endif

File mirage-getopt.h

+/* mirage2iso; getopt wrapper
+ * (c) 2009 Michał Górny
+ * released under 3-clause BSD license
+ */
+
+#ifndef NO_GETOPT_LONG
+#	include <getopt.h>
+#else
+
+enum option_has_arg {
+	no_argument,
+	required_argument
+};
+
+struct option {
+	const char *name;
+	enum option_has_arg has_arg;
+	int *flag;
+	int val;
+};
+
+int optind;
+
+#endif
+
+const int mirage_getopt(int argc, char* const argv[], const struct option *longopts);

File mirage2iso.c

 #	include <unistd.h>
 #endif
 
-#ifdef NO_GETOPT_LONG
-#	error "getopt_long()-lessness not yet supported, sorry."
-#endif
-
-#include <getopt.h>
 #include <sysexits.h>
 
+#include "mirage-getopt.h"
 #include "mirage-wrapper.h"
 
 bool quiet = false;
 
 	int arg;
 
-	while ((arg = getopt_long(argc, argv, "cfqs:SvV?", opts, NULL)) != -1) {
+	while ((arg = mirage_getopt(argc, argv, opts)) != -1) {
 		switch (arg) {
 			case 'c':
 				use_stdout = true;