Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision e8577433c9491c7144a17a047c23afb9ea4cc772)
+++ libcfa/src/Makefile.am	(revision e699eb6380875c2003b6bf18cc2776d92866c117)
@@ -44,5 +44,5 @@
 
 headers = common.hfa fstream.hfa heap.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa \
-		time.hfa stdlib.hfa memory.hfa \
+		time.hfa stdlib.hfa memory.hfa parseargs.hfa \
 		containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
 
Index: libcfa/src/parseargs.cfa
===================================================================
--- libcfa/src/parseargs.cfa	(revision e699eb6380875c2003b6bf18cc2776d92866c117)
+++ libcfa/src/parseargs.cfa	(revision e699eb6380875c2003b6bf18cc2776d92866c117)
@@ -0,0 +1,191 @@
+#include "parseargs.hfa"
+
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+extern "C" {
+	#include <getopt.h>
+	#include <sys/ioctl.h>
+
+	struct FILE;
+	extern FILE * stderr;
+	extern FILE * stdout;
+
+	extern int fileno(FILE *stream);
+
+	extern int fprintf ( FILE * stream, const char * format, ... );
+
+	extern          long long int strtoll (const char* str, char** endptr, int base);
+	extern unsigned long long int strtoull(const char* str, char** endptr, int base);
+}
+
+#include "common.hfa"
+#include "limits.hfa"
+
+void printopt(FILE * out, int width, int max, char sn, const char * ln, const char * help) {
+	int hwidth = max - (11 + width);
+	if(hwidth <= 0) hwidth = max;
+
+	fprintf(out, "  -%c, --%-*s   %.*s\n", sn, width, ln, hwidth, help);
+	for() {
+		help += min(strlen(help), hwidth);
+		if('\0' == *help) break;
+		fprintf(out, "%*s%.*s\n", width + 11, "", hwidth, help);
+	}
+}
+
+void parse_args(
+	int argc,
+	char * argv[],
+	cfa_option options[],
+	size_t opt_count,
+	const char * usage,
+	char ** & left
+) {
+	struct option optarr[opt_count + 2];
+	int width = 0;
+	int max_width = 1_000_000;
+	{
+		int idx = 0;
+		for(i; opt_count) {
+			if(options[i].long_name) {
+				optarr[idx].name = options[i].long_name;
+				optarr[idx].flag = 0p;
+				optarr[idx].val  = options[i].short_name;
+				if(    ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue)
+				    || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) {
+					optarr[idx].has_arg = no_argument;
+				} else {
+					optarr[idx].has_arg = required_argument;
+				}
+				idx++;
+
+				int w = strlen(options[i].long_name);
+				if(w > width) width = w;
+			}
+		}
+		optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h'];
+		optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0];
+	}
+
+	char optstring[opt_count * 3] = { '\0' };
+	{
+		int idx = 0;
+		for(i; opt_count) {
+			optstring[idx] = options[i].short_name;
+			idx++;
+			if(    ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue)
+			    && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
+				optstring[idx] = ':';
+				idx++;
+			}
+		}
+		optstring[idx+0] = 'h';
+		optstring[idx+1] = '\0';
+	}
+
+	FILE * out = stderr;
+	NEXT_ARG:
+	for() {
+		int idx = 0;
+		int opt = getopt_long(argc, argv, optstring, optarr, &idx);
+		switch(opt) {
+			case -1:
+				if(&left != 0p) left = argv + optind;
+				return;
+			case 'h':
+				out = stdout;
+			case '?':
+				goto USAGE;
+			default:
+				for(i; opt_count) {
+					if(opt == options[i].short_name) {
+						const char * arg = optarg ? optarg : "";
+						bool success = options[i].parse( arg, options[i].variable );
+						if(success) continue NEXT_ARG;
+
+						fprintf(out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt);
+						goto USAGE;
+					}
+				}
+				abort("Internal parse arg error\n");
+		}
+
+	}
+
+	USAGE:;
+	int outfd = fileno(out);
+	if(isatty(outfd)) {
+		struct winsize size;
+		int ret = ioctl(outfd, TIOCGWINSZ, &size);
+		if(ret < 0) abort( "ioctl error: (%d) %s\n", (int)errno, strerror(errno) );
+		max_width = size.ws_col;
+	}
+
+	fprintf(out, "Usage:\n  %s %s\n", argv[0], usage);
+
+	for(i; opt_count) {
+		printopt(out, width, max_width, options[i].short_name, options[i].long_name, options[i].help);
+	}
+	fprintf(out, "  -%c, --%-*s   %s\n", 'h', width, "help", "print this help message");
+	exit(out == stdout ? 0 : 1);
+}
+
+bool parse_yesno(const char * arg, bool & value ) {
+	if(strcmp(arg, "yes") == 0) {
+		value = true;
+		return true;
+	}
+
+	if(strcmp(arg, "no") == 0) {
+		value = false;
+		return true;
+	}
+
+	return false;
+}
+
+bool parse_settrue (const char *, bool & value ) {
+	value = true;
+	return true;
+}
+
+bool parse_setfalse(const char *, bool & value )  {
+	value = false;
+	return true;
+}
+
+bool parse(const char * arg, const char * & value ) {
+	value = arg;
+	return true;
+}
+
+bool parse(const char * arg, unsigned & value) {
+	char * end;
+	unsigned long long int r = strtoull(arg, &end, 10);
+	if(*end != '\0') return false;
+	if(r > (unsigned)MAX) return false;
+
+	value = r;
+	return true;
+}
+
+bool parse(const char * arg, size_t & value) {
+	char * end;
+	unsigned long long int r = strtoull(arg, &end, 10);
+	if(*end != '\0') return false;
+	if(r > (size_t)MAX) return false;
+
+	value = r;
+	return true;
+}
+
+bool parse(const char * arg, int & value) {
+	char * end;
+	int r = strtoll(arg, &end, 10);
+	if(*end != '\0') return false;
+
+	value = r;
+	return true;
+}
Index: libcfa/src/parseargs.hfa
===================================================================
--- libcfa/src/parseargs.hfa	(revision e699eb6380875c2003b6bf18cc2776d92866c117)
+++ libcfa/src/parseargs.hfa	(revision e699eb6380875c2003b6bf18cc2776d92866c117)
@@ -0,0 +1,42 @@
+#pragma once
+
+struct cfa_option {
+      char short_name;
+      const char * long_name;
+      const char * help;
+      void * variable;
+      bool (*parse)(const char *, void * );
+};
+
+extern cfa_option last_option;
+
+static inline void ?{}( cfa_option & this ) {}
+
+forall(dtype T | { bool parse(const char *, T & ); })
+static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable ) {
+      this.short_name = short_name;
+      this.long_name  = long_name;
+      this.help       = help;
+      this.variable   = (void*)&variable;
+      this.parse      = (bool (*)(const char *, void * ))parse;
+}
+
+forall(dtype T)
+static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable, bool (*parse)(const char *, T & )) {
+      this.short_name = short_name;
+      this.long_name  = long_name;
+      this.help       = help;
+      this.variable   = (void*)&variable;
+      this.parse      = (bool (*)(const char *, void * ))parse;
+}
+
+void parse_args( int argc, char * argv[], cfa_option options[], size_t opt_count, const char * usage, char ** & left );
+
+bool parse_yesno   (const char *, bool & );
+bool parse_settrue (const char *, bool & );
+bool parse_setfalse(const char *, bool & );
+
+bool parse(const char *, const char * & );
+bool parse(const char *, unsigned & );
+bool parse(const char *, size_t & );
+bool parse(const char *, int & );
