From d82cd6acdece59424a9e66d772da6ceed5b45801 Mon Sep 17 00:00:00 2001
From: Andre Maroneze <andre.maroneze@cea.fr>
Date: Tue, 2 Feb 2021 21:36:03 +0100
Subject: [PATCH] [kgflags] add new case study

---
 Makefile                                      |    1 +
 README.md                                     |    1 +
 kgflags/.frama-c/GNUmakefile                  |   48 +
 kgflags/.frama-c/fc_stubs.c                   |   23 +
 .../.frama-c/kgflags-full_api.eva/alarms.csv  |   90 +
 .../.frama-c/kgflags-full_api.eva/metrics.log |   42 +
 .../.frama-c/kgflags-full_api.eva/nonterm.log |   15 +
 .../kgflags-full_api.eva/warnings.log         |   47 +
 .../kgflags-full_api.parse/framac.ast         | 1779 +++++++++++++++++
 .../kgflags-full_api.parse/metrics.log        |   50 +
 .../kgflags-full_api.parse/warnings.log       |    0
 .../.frama-c/kgflags-simple.eva/alarms.csv    |   36 +
 .../.frama-c/kgflags-simple.eva/metrics.log   |   35 +
 .../.frama-c/kgflags-simple.eva/nonterm.log   |    0
 .../.frama-c/kgflags-simple.eva/warnings.log  |    5 +
 .../.frama-c/kgflags-simple.parse/framac.ast  | 1535 ++++++++++++++
 .../.frama-c/kgflags-simple.parse/metrics.log |   55 +
 .../kgflags-simple.parse/warnings.log         |    0
 kgflags/.frama-c/path.mk                      |    7 +
 kgflags/LICENSE                               |   21 +
 kgflags/examples/full_api.c                   |   60 +
 kgflags/examples/simple.c                     |   14 +
 kgflags/kgflags.h                             |  851 ++++++++
 kgflags/readme.md                             |   75 +
 kgflags/tests/full_api_output                 |   31 +
 kgflags/tests/run_tests.sh                    |   79 +
 kgflags/tests/tests.c                         |  530 +++++
 kgflags/tests/update_full_api_output.sh       |   11 +
 28 files changed, 5441 insertions(+)
 create mode 100644 kgflags/.frama-c/GNUmakefile
 create mode 100644 kgflags/.frama-c/fc_stubs.c
 create mode 100644 kgflags/.frama-c/kgflags-full_api.eva/alarms.csv
 create mode 100644 kgflags/.frama-c/kgflags-full_api.eva/metrics.log
 create mode 100644 kgflags/.frama-c/kgflags-full_api.eva/nonterm.log
 create mode 100644 kgflags/.frama-c/kgflags-full_api.eva/warnings.log
 create mode 100644 kgflags/.frama-c/kgflags-full_api.parse/framac.ast
 create mode 100644 kgflags/.frama-c/kgflags-full_api.parse/metrics.log
 create mode 100644 kgflags/.frama-c/kgflags-full_api.parse/warnings.log
 create mode 100644 kgflags/.frama-c/kgflags-simple.eva/alarms.csv
 create mode 100644 kgflags/.frama-c/kgflags-simple.eva/metrics.log
 create mode 100644 kgflags/.frama-c/kgflags-simple.eva/nonterm.log
 create mode 100644 kgflags/.frama-c/kgflags-simple.eva/warnings.log
 create mode 100644 kgflags/.frama-c/kgflags-simple.parse/framac.ast
 create mode 100644 kgflags/.frama-c/kgflags-simple.parse/metrics.log
 create mode 100644 kgflags/.frama-c/kgflags-simple.parse/warnings.log
 create mode 100644 kgflags/.frama-c/path.mk
 create mode 100644 kgflags/LICENSE
 create mode 100644 kgflags/examples/full_api.c
 create mode 100644 kgflags/examples/simple.c
 create mode 100644 kgflags/kgflags.h
 create mode 100644 kgflags/readme.md
 create mode 100644 kgflags/tests/full_api_output
 create mode 100755 kgflags/tests/run_tests.sh
 create mode 100644 kgflags/tests/tests.c
 create mode 100755 kgflags/tests/update_full_api_output.sh

diff --git a/Makefile b/Makefile
index 10ebfcd4f..4e6352fbd 100644
--- a/Makefile
+++ b/Makefile
@@ -61,6 +61,7 @@ TARGETS=\
   icpc \
   itc-benchmarks \
   jsmn \
+  kgflags \
   khash \
   kilo \
   libmodbus \
diff --git a/README.md b/README.md
index 9e9c7550a..34471bc8b 100644
--- a/README.md
+++ b/README.md
@@ -132,6 +132,7 @@ when available. We also summarize the license of each directory below.
 - `icpc`: Unlicense
 - `itc-benchmarks`: BSD 2-clause, see `COPYING`
 - `jsmn`: MIT
+- `kgflags`: MIT, see `LICENSE`
 - `khash`: MIT
 - `kilo`: BSD 2-clause "Simplified"
           (see https://github.com/antirez/kilo/blob/master/LICENSE)
diff --git a/kgflags/.frama-c/GNUmakefile b/kgflags/.frama-c/GNUmakefile
new file mode 100644
index 000000000..d71141d8d
--- /dev/null
+++ b/kgflags/.frama-c/GNUmakefile
@@ -0,0 +1,48 @@
+# Makefile template for Frama-C/Eva case studies.
+# For details and usage information, see the Frama-C User Manual.
+
+### Prologue. Do not modify this block. #######################################
+-include path.mk
+FRAMAC ?= frama-c
+include $(shell $(FRAMAC)-config -print-share-path)/analysis-scripts/prologue.mk
+###############################################################################
+
+# Edit below as needed. Suggested flags are optional.
+
+MACHDEP = x86_64
+
+## Preprocessing flags (for -cpp-extra-args)
+CPPFLAGS    += \
+
+## General flags
+FCFLAGS     += \
+  -main eva_main \
+  -add-symbolic-path=..:. \
+  -kernel-warn-key annot:missing-spec=abort \
+  -kernel-warn-key typing:implicit-function-declaration=abort \
+
+## Eva-specific flags
+EVAFLAGS    += \
+  -eva-warn-key builtins:missing-spec=abort \
+
+## GUI-only flags
+FCGUIFLAGS += \
+
+## Analysis targets (suffixed with .eva)
+TARGETS = kgflags-simple.eva kgflags-full_api.eva
+
+### Each target <t>.eva needs a rule <t>.parse with source files as prerequisites
+kgflags-simple.parse: \
+  fc_stubs.c \
+  ../examples/simple.c \
+
+kgflags-full_api.parse: \
+  fc_stubs.c \
+  ../examples/full_api.c \
+
+### Epilogue. Do not modify this block. #######################################
+include $(shell $(FRAMAC)-config -print-share-path)/analysis-scripts/epilogue.mk
+###############################################################################
+
+# optional, for OSCS
+-include ../../Makefile.common
diff --git a/kgflags/.frama-c/fc_stubs.c b/kgflags/.frama-c/fc_stubs.c
new file mode 100644
index 000000000..fad866f21
--- /dev/null
+++ b/kgflags/.frama-c/fc_stubs.c
@@ -0,0 +1,23 @@
+// Stub for a main function which reads arguments from the command line, to be
+// used by the Eva plug-in.
+// This stub emulates non-deterministic input of up to 5 arguments, each up
+// to 256 characters long. This is sufficient to ensure arbitrary input in
+// virtually every case.
+// Do not forget to add option '-main eva_main' in order to use this stub.
+
+#ifdef __FRAMAC__
+# include "__fc_builtin.h"
+int main(int, char **);
+static volatile int nondet;
+int eva_main() {
+  int argc = Frama_C_interval(0, 5);
+  char argv0[256], argv1[256], argv2[256], argv3[256], argv4[256];
+  char *argv[6] = {argv0, argv1, argv2, argv3, argv4, 0};
+  //@ loop unroll 5;
+  for (int i = 0; i < 5; i++) {
+    Frama_C_make_unknown(argv[i], 255);
+    argv[i][255] = 0;
+  }
+  return main(argc, argv);
+}
+#endif // __FRAMAC__
diff --git a/kgflags/.frama-c/kgflags-full_api.eva/alarms.csv b/kgflags/.frama-c/kgflags-full_api.eva/alarms.csv
new file mode 100644
index 000000000..916466fa0
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-full_api.eva/alarms.csv
@@ -0,0 +1,90 @@
+directory	file	line	function	property kind	status	property
+.	kgflags.h	402	kgflags_print_errors	initialization	Unknown	\initialized(&err->kind)
+.	kgflags.h	404	fprintf_va_1	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	404	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	404	kgflags_print_errors	precondition of fprintf_va_1	Unknown	valid_read_string(param1)
+.	kgflags.h	408	fprintf_va_2	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	408	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	408	kgflags_print_errors	precondition of fprintf_va_2	Unknown	valid_read_string(param1)
+.	kgflags.h	412	fprintf_va_3	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	412	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	412	kgflags_print_errors	precondition of fprintf_va_3	Unknown	valid_read_string(param1)
+.	kgflags.h	416	fprintf_va_4	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	416	fprintf_va_4	precondition	Unknown	valid_read_string(param2)
+.	kgflags.h	416	kgflags_print_errors	initialization	Unknown	\initialized(&err->arg)
+.	kgflags.h	416	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	416	kgflags_print_errors	precondition of fprintf_va_4	Unknown	valid_read_string(param1)
+.	kgflags.h	416	kgflags_print_errors	precondition of fprintf_va_4	Unknown	valid_read_string(param2)
+.	kgflags.h	420	fprintf_va_5	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	420	fprintf_va_5	precondition	Unknown	valid_read_string(param2)
+.	kgflags.h	420	kgflags_print_errors	initialization	Unknown	\initialized(&err->arg)
+.	kgflags.h	420	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	420	kgflags_print_errors	precondition of fprintf_va_5	Unknown	valid_read_string(param1)
+.	kgflags.h	420	kgflags_print_errors	precondition of fprintf_va_5	Unknown	valid_read_string(param2)
+.	kgflags.h	432	fprintf_va_8	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	432	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	432	kgflags_print_errors	precondition of fprintf_va_8	Unknown	valid_read_string(param1)
+.	kgflags.h	436	fprintf_va_9	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	436	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	436	kgflags_print_errors	precondition of fprintf_va_9	Unknown	valid_read_string(param1)
+.	kgflags.h	440	fprintf_va_10	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	440	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	440	kgflags_print_errors	precondition of fprintf_va_10	Unknown	valid_read_string(param1)
+.	kgflags.h	467	fprintf_va_16	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	467	fprintf_va_16	precondition	Unknown	valid_read_string(param3)
+.	kgflags.h	467	kgflags_print_usage	precondition of fprintf_va_16	Unknown	valid_read_string(param1)
+.	kgflags.h	467	kgflags_print_usage	precondition of fprintf_va_16	Unknown	valid_read_string(param3)
+.	kgflags.h	475	fprintf_va_18	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	475	kgflags_print_usage	precondition of fprintf_va_18	Unknown	valid_read_string(param1)
+.	kgflags.h	482	fprintf_va_20	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	482	kgflags_print_usage	precondition of fprintf_va_20	Unknown	valid_read_string(param1)
+.	kgflags.h	489	fprintf_va_22	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	489	kgflags_print_usage	precondition of fprintf_va_22	Unknown	valid_read_string(param1)
+.	kgflags.h	493	fprintf_va_23	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	493	kgflags_print_usage	precondition of fprintf_va_23	Unknown	valid_read_string(param1)
+.	kgflags.h	497	fprintf_va_24	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	497	kgflags_print_usage	precondition of fprintf_va_24	Unknown	valid_read_string(param1)
+.	kgflags.h	504	fprintf_va_25	precondition	Unknown	valid_read_string(param0)
+.	kgflags.h	504	kgflags_print_usage	precondition of fprintf_va_25	Unknown	valid_read_string(param0)
+.	kgflags.h	522	kgflags_string_array_get_item	mem_access	Unknown	\valid_read(arr->_items + at)
+.	kgflags.h	533	kgflags_int_array_get_item	mem_access	Unknown	\valid_read(arr->_items + at)
+.	kgflags.h	550	kgflags_double_array_get_item	mem_access	Unknown	\valid_read(arr->_items + at)
+.	kgflags.h	608	_kgflags_get_flag	precondition of strcmp	Unknown	valid_string_s1: valid_read_string(s1)
+.	kgflags.h	608	_kgflags_get_flag	precondition of strcmp	Unknown	valid_string_s2: valid_read_string(s2)
+.	kgflags.h	611	_kgflags_get_flag	precondition of strstr	Unknown	valid_string_haystack: valid_read_string(haystack)
+.	kgflags.h	612	_kgflags_get_flag	precondition of strcmp	Unknown	valid_string_s1: valid_read_string(s1)
+.	kgflags.h	612	_kgflags_get_flag	precondition of strcmp	Unknown	valid_string_s2: valid_read_string(s2)
+.	kgflags.h	626	_kgflags_parse_int	precondition of strtol	Unknown	valid_nptr: \valid_read(nptr)
+.	kgflags.h	627	_kgflags_parse_int	ptr_comparison	Unknown	\pointer_comparable((void *)end, (void *)str)
+.	kgflags.h	627	_kgflags_parse_int	mem_access	Unknown	\valid_read(end)
+.	kgflags.h	639	_kgflags_parse_double	precondition of strtod	Unknown	valid_nptr: \valid_read(nptr)
+.	kgflags.h	640	_kgflags_parse_double	ptr_comparison	Unknown	\pointer_comparable((void *)end, (void *)str)
+.	kgflags.h	640	_kgflags_parse_double	mem_access	Unknown	\valid_read(end)
+.	kgflags.h	641	_kgflags_parse_double	is_nan_or_infinite	Unknown	\is_finite(res)
+.	kgflags.h	641	_kgflags_parse_double	is_nan_or_infinite	Invalid or unreachable	\is_finite((float)INFINITY)
+.	kgflags.h	675	_kgflags_assign_default_values	mem_access	Unknown	\valid(flag->result.bool_value)
+.	kgflags.h	680	_kgflags_assign_default_values	mem_access	Unknown	\valid(flag->result.int_value)
+.	kgflags.h	685	_kgflags_assign_default_values	mem_access	Unknown	\valid(flag->result.double_value)
+.	kgflags.h	735	_kgflags_parse_flag	mem_access	Unknown	\valid(flag->result.bool_value)
+.	kgflags.h	753	_kgflags_parse_flag	mem_access	Unknown	\valid(flag->result.int_value)
+.	kgflags.h	784	_kgflags_parse_flag	signed_overflow	Unknown	count + 1 ≤ 2147483647
+.	kgflags.h	787	_kgflags_parse_flag	mem_access	Unknown	\valid(&arr->_items)
+.	kgflags.h	788	_kgflags_parse_flag	mem_access	Unknown	\valid(&arr->_count)
+.	kgflags.h	809	_kgflags_parse_flag	signed_overflow	Unknown	count_0 + 1 ≤ 2147483647
+.	kgflags.h	813	_kgflags_parse_flag	mem_access	Unknown	\valid(&arr_0->_items)
+.	kgflags.h	814	_kgflags_parse_flag	mem_access	Unknown	\valid(&arr_0->_count)
+.	kgflags.h	836	_kgflags_parse_flag	signed_overflow	Unknown	count_1 + 1 ≤ 2147483647
+.	kgflags.h	840	_kgflags_parse_flag	mem_access	Unknown	\valid(&arr_1->_items)
+.	kgflags.h	841	_kgflags_parse_flag	mem_access	Unknown	\valid(&arr_1->_count)
+FRAMAC_SHARE/libc	stdlib.h	98	strtod	precondition	Unknown	valid_nptr: \valid_read(nptr)
+FRAMAC_SHARE/libc	stdlib.h	165	strtol	precondition	Unknown	valid_nptr: \valid_read(nptr)
+FRAMAC_SHARE/libc	string.h	137	strcmp	precondition	Unknown	valid_string_s1: valid_read_string(s1)
+FRAMAC_SHARE/libc	string.h	138	strcmp	precondition	Unknown	valid_string_s2: valid_read_string(s2)
+FRAMAC_SHARE/libc	string.h	220	strstr	precondition	Unknown	valid_string_haystack: valid_read_string(haystack)
+examples	full_api.c	34	main	precondition of printf_va_1	Unknown	valid_read_string(param0)
+examples	full_api.c	34	printf_va_1	precondition	Unknown	valid_read_string(param0)
+examples	full_api.c	37	main	is_nan_or_infinite	Unknown	\is_finite(double_val)
+examples	full_api.c	41	main	precondition of printf_va_6	Unknown	valid_read_string(param1)
+examples	full_api.c	41	printf_va_6	precondition	Unknown	valid_read_string(param1)
+examples	full_api.c	56	main	precondition of printf_va_11	Unknown	valid_read_string(param1)
+examples	full_api.c	56	printf_va_11	precondition	Unknown	valid_read_string(param1)
diff --git a/kgflags/.frama-c/kgflags-full_api.eva/metrics.log b/kgflags/.frama-c/kgflags-full_api.eva/metrics.log
new file mode 100644
index 000000000..c3db58390
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-full_api.eva/metrics.log
@@ -0,0 +1,42 @@
+[metrics] Eva coverage statistics
+=======================
+Syntactically reachable functions = 34 (out of 34)
+Semantically reached functions = 34
+Coverage estimation = 100.0%
+[metrics] Statements analyzed by Eva
+--------------------------
+736 stmts in analyzed functions, 707 stmts analyzed (96.1%)
+_kgflags_add_error: 9 stmts out of 9 (100.0%)
+_kgflags_add_non_flag_arg: 9 stmts out of 9 (100.0%)
+_kgflags_consume_arg: 8 stmts out of 8 (100.0%)
+_kgflags_get_flag: 29 stmts out of 29 (100.0%)
+_kgflags_get_flag_name: 15 stmts out of 15 (100.0%)
+_kgflags_is_flag: 3 stmts out of 3 (100.0%)
+_kgflags_peek_arg: 6 stmts out of 6 (100.0%)
+eva_main: 13 stmts out of 13 (100.0%)
+kgflags_bool: 18 stmts out of 18 (100.0%)
+kgflags_double: 11 stmts out of 11 (100.0%)
+kgflags_double_array: 11 stmts out of 11 (100.0%)
+kgflags_double_array_get_count: 2 stmts out of 2 (100.0%)
+kgflags_get_non_flag_args_count: 2 stmts out of 2 (100.0%)
+kgflags_int: 11 stmts out of 11 (100.0%)
+kgflags_int_array: 11 stmts out of 11 (100.0%)
+kgflags_int_array_get_count: 2 stmts out of 2 (100.0%)
+kgflags_print_errors: 40 stmts out of 40 (100.0%)
+kgflags_set_custom_description: 2 stmts out of 2 (100.0%)
+kgflags_set_prefix: 2 stmts out of 2 (100.0%)
+kgflags_string: 11 stmts out of 11 (100.0%)
+kgflags_string_array: 11 stmts out of 11 (100.0%)
+kgflags_string_array_get_count: 2 stmts out of 2 (100.0%)
+main: 89 stmts out of 89 (100.0%)
+kgflags_parse: 47 stmts out of 48 (97.9%)
+_kgflags_parse_flag: 121 stmts out of 124 (97.6%)
+kgflags_print_usage: 106 stmts out of 110 (96.4%)
+kgflags_int_array_get_item: 15 stmts out of 16 (93.8%)
+kgflags_get_non_flag_arg: 8 stmts out of 9 (88.9%)
+kgflags_string_array_get_item: 8 stmts out of 9 (88.9%)
+_kgflags_parse_int: 21 stmts out of 24 (87.5%)
+kgflags_double_array_get_item: 14 stmts out of 16 (87.5%)
+_kgflags_assign_default_values: 27 stmts out of 31 (87.1%)
+_kgflags_add_flag: 9 stmts out of 12 (75.0%)
+_kgflags_parse_double: 14 stmts out of 20 (70.0%)
diff --git a/kgflags/.frama-c/kgflags-full_api.eva/nonterm.log b/kgflags/.frama-c/kgflags-full_api.eva/nonterm.log
new file mode 100644
index 000000000..09bee4fef
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-full_api.eva/nonterm.log
@@ -0,0 +1,15 @@
+kgflags.h:641:[nonterm] warning: non-terminating statement
+stack 1: _kgflags_parse_double :: kgflags.h:765 <-
+         _kgflags_parse_flag :: kgflags.h:380 <-
+         kgflags_parse :: examples/full_api.c:28 <-
+         main :: fc_stubs.c:21 <-
+         eva_main
+stack 2: _kgflags_parse_double :: kgflags.h:830 <-
+         _kgflags_parse_flag :: kgflags.h:380 <-
+         kgflags_parse :: examples/full_api.c:28 <-
+         main :: fc_stubs.c:21 <-
+         eva_main
+stack 3: _kgflags_parse_double :: kgflags.h:552 <-
+         kgflags_double_array_get_item :: examples/full_api.c:51 <-
+         main :: fc_stubs.c:21 <-
+         eva_main
diff --git a/kgflags/.frama-c/kgflags-full_api.eva/warnings.log b/kgflags/.frama-c/kgflags-full_api.eva/warnings.log
new file mode 100644
index 000000000..b06e0040e
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-full_api.eva/warnings.log
@@ -0,0 +1,47 @@
+examples/full_api.c:37:[eva:garbled-mix] warning: The specification of function printf_va_4 has generated a garbled mix for assigns clause __fc_stdout->__fc_FILE_data.
+examples/full_api.c:39:[eva:garbled-mix] warning: The specification of function printf_va_5 has generated a garbled mix for assigns clause __fc_stdout->__fc_FILE_data.
+examples/full_api.c:41:[eva:garbled-mix] warning: The specification of function printf_va_6 has generated a garbled mix for assigns clause __fc_stdout->__fc_FILE_data.
+examples/full_api.c:44:[eva:garbled-mix] warning: The specification of function printf_va_7 has generated a garbled mix for assigns clause __fc_stdout->__fc_FILE_data.
+kgflags.h:626:[eva:garbled-mix] warning: The specification of function strtol has generated a garbled mix for assigns clause *endptr.
+examples/full_api.c:46:[eva:garbled-mix] warning: The specification of function printf_va_8 has generated a garbled mix for assigns clause __fc_stdout->__fc_FILE_data.
+examples/full_api.c:49:[eva:garbled-mix] warning: The specification of function printf_va_9 has generated a garbled mix for assigns clause __fc_stdout->__fc_FILE_data.
+kgflags.h:639:[eva:garbled-mix] warning: The specification of function strtod has generated a garbled mix for assigns clause *endptr.
+examples/full_api.c:51:[eva:garbled-mix] warning: The specification of function printf_va_10 has generated a garbled mix for assigns clause __fc_stdout->__fc_FILE_data.
+examples/full_api.c:56:[eva:garbled-mix] warning: The specification of function printf_va_11 has generated a garbled mix for assigns clause __fc_stdout->__fc_FILE_data.
+fc_stubs.c:21:[eva:locals-escaping] warning: locals {string_val} escaping the scope of main through _kgflags_g
+fc_stubs.c:21:[eva:locals-escaping] warning: locals {bool_val, int_val, double_val, string_arr, int_arr, double_arr} escaping the scope of main through _kgflags_g
+fc_stubs.c:21:[eva:locals-escaping] warning: locals {int_val, double_val, string_arr, int_arr, double_arr} escaping the scope of main through _kgflags_g
+fc_stubs.c:21:[eva:locals-escaping] warning: locals {double_val, string_arr, int_arr, double_arr} escaping the scope of main through _kgflags_g
+fc_stubs.c:21:[eva:locals-escaping] warning: locals {string_arr, int_arr, double_arr} escaping the scope of main through _kgflags_g
+fc_stubs.c:21:[eva:locals-escaping] warning: locals {int_arr, double_arr} escaping the scope of main through _kgflags_g
+fc_stubs.c:21:[eva:locals-escaping] warning: locals {double_arr} escaping the scope of main through _kgflags_g
+[eva:garbled-mix] warning: Garbled mix generated during analysis:
+{{ garbled mix of &{argv1; argv2; argv3; argv4}
+  (origin: Misaligned {kgflags.h:657}) }}
+{{ garbled mix of &{"bool"; "int"; "double"; "string-array"; "int-array";
+                    "double-array"} (origin: Misaligned {kgflags.h:657}) }}
+{{ garbled mix of &{argv} (origin: Merge {kgflags.h:849}) }}
+{{ garbled mix of &{"string"; "bool"; "int"; "double"; "string-array";
+                    "int-array"; "double-array"}
+  (origin: Misaligned {kgflags.h:657}) }}
+{{ garbled mix of &{"string"} (origin: Misaligned {kgflags.h:657}) }}
+{{ garbled mix of &{argv} (origin: Merge {kgflags.h:735}) }}
+{{ garbled mix of &{argv} (origin: Misaligned {examples/full_api.c:37}) }}
+{{ garbled mix of &{argv} (origin: Misaligned {kgflags.h:522}) }}
+{{ garbled mix of &{argv1} (origin: Misaligned {kgflags.h:522}) }}
+{{ garbled mix of &{argv3} (origin: Misaligned {kgflags.h:522}) }}
+{{ garbled mix of &{argv2} (origin: Misaligned {kgflags.h:522}) }}
+{{ garbled mix of &{argv4} (origin: Misaligned {kgflags.h:522}) }}
+{{ garbled mix of &{argv0} (origin: Misaligned {kgflags.h:522}) }}
+{{ garbled mix of &{argv} (origin: Misaligned {kgflags.h:533}) }}
+{{ garbled mix of &{argv1} (origin: Misaligned {kgflags.h:533}) }}
+{{ garbled mix of &{argv3} (origin: Misaligned {kgflags.h:533}) }}
+{{ garbled mix of &{argv2} (origin: Misaligned {kgflags.h:533}) }}
+{{ garbled mix of &{argv4} (origin: Misaligned {kgflags.h:533}) }}
+{{ garbled mix of &{argv0} (origin: Misaligned {kgflags.h:533}) }}
+{{ garbled mix of &{argv} (origin: Misaligned {kgflags.h:550}) }}
+{{ garbled mix of &{argv1} (origin: Misaligned {kgflags.h:550}) }}
+{{ garbled mix of &{argv3} (origin: Misaligned {kgflags.h:550}) }}
+{{ garbled mix of &{argv2} (origin: Misaligned {kgflags.h:550}) }}
+{{ garbled mix of &{argv4} (origin: Misaligned {kgflags.h:550}) }}
+{{ garbled mix of &{argv0} (origin: Misaligned {kgflags.h:550}) }}
diff --git a/kgflags/.frama-c/kgflags-full_api.parse/framac.ast b/kgflags/.frama-c/kgflags-full_api.parse/framac.ast
new file mode 100644
index 000000000..f57f14198
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-full_api.parse/framac.ast
@@ -0,0 +1,1779 @@
+/* Generated by Frama-C */
+#include "__fc_builtin.h"
+#include "errno.h"
+#include "math.h"
+#include "stdarg.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "strings.h"
+struct kgflags_string_array {
+   char **_items ;
+   int _count ;
+};
+typedef struct kgflags_string_array kgflags_string_array_t;
+struct kgflags_int_array {
+   char **_items ;
+   int _count ;
+};
+typedef struct kgflags_int_array kgflags_int_array_t;
+struct kgflags_double_array {
+   char **_items ;
+   int _count ;
+};
+typedef struct kgflags_double_array kgflags_double_array_t;
+enum _kgflags_flag_kind {
+    KGFLAGS_FLAG_KIND_NONE = 0,
+    KGFLAGS_FLAG_KIND_STRING = 1,
+    KGFLAGS_FLAG_KIND_BOOL = 2,
+    KGFLAGS_FLAG_KIND_INT = 3,
+    KGFLAGS_FLAG_KIND_DOUBLE = 4,
+    KGFLAGS_FLAG_KIND_STRING_ARRAY = 5,
+    KGFLAGS_FLAG_KIND_INT_ARRAY = 6,
+    KGFLAGS_FLAG_KIND_DOUBLE_ARRAY = 7
+};
+typedef enum _kgflags_flag_kind _kgflags_flag_kind_t;
+union __anonunion_default_value_1 {
+   char const *string_value ;
+   _Bool bool_value ;
+   int int_value ;
+   double double_value ;
+};
+union __anonunion_result_2 {
+   char const **string_value ;
+   _Bool *bool_value ;
+   int *int_value ;
+   double *double_value ;
+   kgflags_string_array_t *string_array ;
+   kgflags_int_array_t *int_array ;
+   kgflags_double_array_t *double_array ;
+};
+struct _kgflags_flag {
+   char const *name ;
+   char const *description ;
+   union __anonunion_default_value_1 default_value ;
+   union __anonunion_result_2 result ;
+   _Bool assigned ;
+   _Bool error ;
+   _Bool required ;
+   _kgflags_flag_kind_t kind ;
+};
+typedef struct _kgflags_flag _kgflags_flag_t;
+enum _kgflags_error_kind {
+    KGFLAGS_ERROR_KIND_NONE = 0,
+    KGFLAGS_ERROR_KIND_MISSING_VALUE = 1,
+    KGFLAGS_ERROR_KIND_UNKNOWN_FLAG = 2,
+    KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG = 3,
+    KGFLAGS_ERROR_KIND_INVALID_INT = 4,
+    KGFLAGS_ERROR_KIND_INVALID_DOUBLE = 5,
+    KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS = 6,
+    KGFLAGS_ERROR_KIND_TOO_MANY_NON_FLAG_ARGS = 7,
+    KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT = 8,
+    KGFLAGS_ERROR_KIND_DUPLICATE_FLAG = 9,
+    KGFLAGS_ERROR_KIND_PREFIX_NO = 10
+};
+typedef enum _kgflags_error_kind _kgflags_error_kind_t;
+struct _kgflags_error {
+   char const *flag_name ;
+   char const *arg ;
+   _kgflags_error_kind_t kind ;
+};
+typedef struct _kgflags_error _kgflags_error_t;
+struct __anonstruct__kgflags_g_3 {
+   int flags_count ;
+   _kgflags_flag_t flags[256] ;
+   int non_flag_count ;
+   char const *non_flag_args[512] ;
+   int errors_count ;
+   _kgflags_error_t errors[512] ;
+   char const *flag_prefix ;
+   int arg_cursor ;
+   int argc ;
+   char **argv ;
+   char const *custom_description ;
+};
+int main(int argc, char **argv);
+
+int eva_main(void)
+{
+  char argv0[256];
+  char argv1[256];
+  char argv2[256];
+  char argv3[256];
+  char argv4[256];
+  int tmp_0;
+  int argc = Frama_C_interval(0,5);
+  char *argv[6] = {argv0, argv1, argv2, argv3, argv4, (char *)0};
+  {
+    int i = 0;
+    /*@ loop unroll 5; */
+    while (i < 5) {
+      Frama_C_make_unknown(argv[i],(unsigned long)255);
+      *(argv[i] + 255) = (char)0;
+      i ++;
+    }
+  }
+  tmp_0 = main(argc,argv);
+  return tmp_0;
+}
+
+void kgflags_string(char const *name, char const *default_value,
+                    char const *description, _Bool required,
+                    char const **out_res);
+
+void kgflags_bool(char const *name, _Bool default_value,
+                  char const *description, _Bool required, _Bool *out_res);
+
+void kgflags_int(char const *name, int default_value,
+                 char const *description, _Bool required, int *out_res);
+
+void kgflags_double(char const *name, double default_value,
+                    char const *description, _Bool required, double *out_res);
+
+void kgflags_string_array(char const *name, char const *description,
+                          _Bool required, kgflags_string_array_t *out_arr);
+
+void kgflags_int_array(char const *name, char const *description,
+                       _Bool required, kgflags_int_array_t *out_arr);
+
+void kgflags_double_array(char const *name, char const *description,
+                          _Bool required, kgflags_double_array_t *out_arr);
+
+void kgflags_set_prefix(char const *prefix);
+
+_Bool kgflags_parse(int argc, char **argv);
+
+void kgflags_print_errors(void);
+
+void kgflags_print_usage(void);
+
+void kgflags_set_custom_description(char const *description);
+
+int kgflags_string_array_get_count(kgflags_string_array_t const *arr);
+
+char const *kgflags_string_array_get_item(kgflags_string_array_t const *arr,
+                                          int at);
+
+int kgflags_int_array_get_count(kgflags_int_array_t const *arr);
+
+int kgflags_int_array_get_item(kgflags_int_array_t const *arr, int at);
+
+int kgflags_double_array_get_count(kgflags_double_array_t const *arr);
+
+double kgflags_double_array_get_item(kgflags_double_array_t const *arr,
+                                     int at);
+
+int kgflags_get_non_flag_args_count(void);
+
+char const *kgflags_get_non_flag_arg(int at);
+
+static _Bool _kgflags_is_flag(char const *arg);
+
+static char const *_kgflags_get_flag_name(char const *arg);
+
+static void _kgflags_add_flag(_kgflags_flag_t flag);
+
+static _kgflags_flag_t *_kgflags_get_flag(char const *name,
+                                          _Bool *out_prefix_no);
+
+static int _kgflags_parse_int(char const *str, _Bool *out_ok);
+
+static double _kgflags_parse_double(char const *str, _Bool *out_ok);
+
+static void _kgflags_add_error(_kgflags_error_kind_t kind,
+                               char const *flag_name, char const *arg);
+
+static void _kgflags_assign_default_values(void);
+
+static _Bool _kgflags_add_non_flag_arg(char const *arg);
+
+static char const *_kgflags_consume_arg(void);
+
+static char const *_kgflags_peek_arg(void);
+
+static void _kgflags_parse_flag(_kgflags_flag_t *flag, _Bool prefix_no);
+
+static struct __anonstruct__kgflags_g_3 _kgflags_g;
+void kgflags_string(char const *name, char const *default_value,
+                    char const *description, _Bool required,
+                    char const **out_res)
+{
+  _kgflags_flag_t flag;
+  *out_res = (char const *)0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_STRING;
+  flag.name = name;
+  flag.default_value.string_value = default_value;
+  flag.description = description;
+  flag.required = required;
+  flag.result.string_value = out_res;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_bool(char const *name, _Bool default_value,
+                  char const *description, _Bool required, _Bool *out_res)
+{
+  char *tmp;
+  _kgflags_flag_t flag;
+  *out_res = (_Bool)0;
+  tmp = strstr(name,"no-");
+  ;
+  if ((void *)tmp == (void *)name) {
+    _kgflags_add_error(KGFLAGS_ERROR_KIND_PREFIX_NO,name,(char const *)0);
+    goto return_label;
+  }
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_BOOL;
+  flag.name = name;
+  flag.default_value.bool_value = default_value;
+  flag.description = description;
+  flag.required = required;
+  flag.result.bool_value = out_res;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return_label: return;
+}
+
+void kgflags_int(char const *name, int default_value,
+                 char const *description, _Bool required, int *out_res)
+{
+  _kgflags_flag_t flag;
+  *out_res = 0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_INT;
+  flag.name = name;
+  flag.default_value.int_value = default_value;
+  flag.description = description;
+  flag.required = required;
+  flag.result.int_value = out_res;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_double(char const *name, double default_value,
+                    char const *description, _Bool required, double *out_res)
+{
+  _kgflags_flag_t flag;
+  *out_res = 0.0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_DOUBLE;
+  flag.name = name;
+  flag.default_value.double_value = default_value;
+  flag.description = description;
+  flag.required = required;
+  flag.result.double_value = out_res;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_string_array(char const *name, char const *description,
+                          _Bool required, kgflags_string_array_t *out_arr)
+{
+  _kgflags_flag_t flag;
+  out_arr->_items = (char **)0;
+  out_arr->_count = 0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_STRING_ARRAY;
+  flag.name = name;
+  flag.description = description;
+  flag.required = required;
+  flag.result.string_array = out_arr;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_int_array(char const *name, char const *description,
+                       _Bool required, kgflags_int_array_t *out_arr)
+{
+  _kgflags_flag_t flag;
+  out_arr->_items = (char **)0;
+  out_arr->_count = 0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_INT_ARRAY;
+  flag.name = name;
+  flag.description = description;
+  flag.required = required;
+  flag.result.int_array = out_arr;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_double_array(char const *name, char const *description,
+                          _Bool required, kgflags_double_array_t *out_arr)
+{
+  _kgflags_flag_t flag;
+  out_arr->_items = (char **)0;
+  out_arr->_count = 0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_DOUBLE_ARRAY;
+  flag.name = name;
+  flag.description = description;
+  flag.required = required;
+  flag.result.double_array = out_arr;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_set_prefix(char const *prefix)
+{
+  _kgflags_g.flag_prefix = prefix;
+  return;
+}
+
+_Bool kgflags_parse(int argc, char **argv)
+{
+  _Bool __retres;
+  _kgflags_g.argc = argc;
+  _kgflags_g.argv = argv;
+  _kgflags_g.arg_cursor = 1;
+  if (_kgflags_g.flag_prefix == (char const *)0) _kgflags_g.flag_prefix = "--";
+  if (_kgflags_g.errors_count > 0) {
+    __retres = (_Bool)0;
+    goto return_label;
+  }
+  char const *arg = (char const *)0;
+  while (1) {
+    arg = _kgflags_consume_arg();
+    if (! (arg != (char const *)0)) break;
+    {
+      _kgflags_flag_t *flag = (_kgflags_flag_t *)0;
+      _Bool is_flag = _kgflags_is_flag(arg);
+      _Bool prefix_no = (_Bool)0;
+      if (is_flag) {
+        char const *flag_name = _kgflags_get_flag_name(arg);
+        flag = _kgflags_get_flag(flag_name,& prefix_no);
+        if (flag == (_kgflags_flag_t *)0) {
+          _kgflags_add_error(KGFLAGS_ERROR_KIND_UNKNOWN_FLAG,flag_name,
+                             (char const *)0);
+          continue;
+        }
+      }
+      else {
+        _kgflags_add_non_flag_arg(arg);
+        continue;
+      }
+      if (flag->assigned) _kgflags_add_error(KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT,
+                                             flag->name,(char const *)0);
+      _kgflags_parse_flag(flag,prefix_no);
+    }
+  }
+  _kgflags_assign_default_values();
+  {
+    int i = 0;
+    while (i < _kgflags_g.flags_count) {
+      {
+        _kgflags_flag_t *flag_0 = & _kgflags_g.flags[i];
+        if (flag_0->required) 
+          if (! flag_0->assigned) 
+            if (! flag_0->error) _kgflags_add_error(KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG,
+                                                    flag_0->name,
+                                                    (char const *)0);
+      }
+      i ++;
+    }
+  }
+  if (_kgflags_g.errors_count > 0) {
+    __retres = (_Bool)0;
+    goto return_label;
+  }
+  __retres = (_Bool)1;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_1(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_2(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_3(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_4(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_5(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+ */
+int fprintf_va_6(FILE * __restrict stream, char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+ */
+int fprintf_va_7(FILE * __restrict stream, char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_8(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_9(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_10(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1);
+
+void kgflags_print_errors(void)
+{
+  int i = 0;
+  while (i < _kgflags_g.errors_count) {
+    {
+      _kgflags_error_t *err = & _kgflags_g.errors[i];
+      switch (err->kind) {
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_MISSING_VALUE:
+        {
+          fprintf(__fc_stderr,"Missing value for flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_1 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_UNKNOWN_FLAG:
+        {
+          fprintf(__fc_stderr,"Unrecognized flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_2 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG:
+        {
+          fprintf(__fc_stderr,"Unassigned required flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_3 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_INVALID_INT:
+        {
+          fprintf(__fc_stderr,
+                  "Invalid value for flag: %s%s (got %s, expected integer)\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name,
+                  (char *)err->arg); /* fprintf_va_4 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_INVALID_DOUBLE:
+        {
+          fprintf(__fc_stderr,
+                  "Invalid value for flag: %s%s (got %s, expected number)\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name,
+                  (char *)err->arg); /* fprintf_va_5 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS:
+        {
+          fprintf(__fc_stderr,"Too many flags declared."); /* fprintf_va_6 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_TOO_MANY_NON_FLAG_ARGS:
+        {
+          fprintf(__fc_stderr,
+                  "Too many non-flag arguments passed to program."); /* fprintf_va_7 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT:
+        {
+          fprintf(__fc_stderr,"Multiple assignment of flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_8 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_DUPLICATE_FLAG:
+        {
+          fprintf(__fc_stderr,"Redeclaration of flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_9 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_PREFIX_NO:
+        {
+          fprintf(__fc_stderr,
+                  "Used \"no-\" prefix when declaring boolean flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_10 */
+          break;
+        }
+        default: break;
+      }
+    }
+    i ++;
+  }
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param0 + (0 ..));
+ */
+int fprintf_va_11(FILE * __restrict stream, char const * __restrict format,
+                  char *param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param0 + (0 ..));
+ */
+int fprintf_va_12(FILE * __restrict stream, char const * __restrict format,
+                  char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+ */
+int fprintf_va_13(FILE * __restrict stream, char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_14(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param0 + (0 ..));
+ */
+int fprintf_va_15(FILE * __restrict stream, char const * __restrict format,
+                  char *param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param4);
+    requires valid_read_string(param3);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param4 + (0 ..))),
+            (indirect: *(param3 + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param4 + (0 ..)),
+            *(param3 + (0 ..)), *(param2 + (0 ..)), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_16(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2, char *param3,
+                  char *param4);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param0 + (0 ..));
+ */
+int fprintf_va_17(FILE * __restrict stream, char const * __restrict format,
+                  char *param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_18(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), param0;
+ */
+int fprintf_va_19(FILE * __restrict stream, char const * __restrict format,
+                  int param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_20(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), param0;
+ */
+int fprintf_va_21(FILE * __restrict stream, char const * __restrict format,
+                  double param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_22(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_23(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_24(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param0 + (0 ..));
+ */
+int fprintf_va_25(FILE * __restrict stream, char const * __restrict format,
+                  char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+ */
+int fprintf_va_26(FILE * __restrict stream, char const * __restrict format);
+
+void kgflags_print_usage(void)
+{
+  if (_kgflags_g.custom_description == (char const *)0) fprintf(__fc_stderr,
+                                                                "Usage of %s:\n",
+                                                                *(_kgflags_g.argv + 0)); /* fprintf_va_11 */
+  else fprintf(__fc_stderr,"%s\n",(char *)_kgflags_g.custom_description); /* fprintf_va_12 */
+  fprintf(__fc_stderr,"Flags:\n"); /* fprintf_va_13 */
+  {
+    int i = 0;
+    while (i < _kgflags_g.flags_count) {
+      {
+        _kgflags_flag_t *flag = & _kgflags_g.flags[i];
+        switch (flag->kind) {
+          char const *tmp;
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_STRING:
+          { /* sequence */
+            if (flag->required) tmp = ")"; else tmp = ", optional)";
+            ;
+            ;
+            ;
+          }
+          fprintf(__fc_stderr,"\t%s%s\t(string%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                  (char *)tmp); /* fprintf_va_14 */
+          if (! flag->required) fprintf(__fc_stderr,"\t\tDefault: %s\n",
+                                        (char *)flag->default_value.string_value); /* fprintf_va_15 */
+          break;
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_BOOL:
+          {
+            char const *tmp_0;
+            if (flag->required) tmp_0 = ")"; else tmp_0 = ", optional)";
+            ;
+            ;
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s, %sno-%s\t(boolean%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_0); /* fprintf_va_16 */
+            if (! flag->required) {
+              char const *tmp_1;
+              if (flag->default_value.bool_value) tmp_1 = "True";
+              else tmp_1 = "False";
+              ;
+              fprintf(__fc_stderr,"\t\tDefault: %s\n",(char *)tmp_1); /* fprintf_va_17 */
+            }
+            break;
+          }
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_INT:
+          {
+            char const *tmp_2;
+            if (flag->required) tmp_2 = ")"; else tmp_2 = ", optional)";
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s\t(integer%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_2); /* fprintf_va_18 */
+            if (! flag->required) fprintf(__fc_stderr,"\t\tDefault: %d\n",
+                                          flag->default_value.int_value); /* fprintf_va_19 */
+            break;
+          }
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_DOUBLE:
+          {
+            char const *tmp_3;
+            if (flag->required) tmp_3 = ")"; else tmp_3 = ", optional)";
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s\t(float%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_3); /* fprintf_va_20 */
+            if (! flag->required) fprintf(__fc_stderr,"\t\tDefault: %1.4g\n",
+                                          flag->default_value.double_value); /* fprintf_va_21 */
+            break;
+          }
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_STRING_ARRAY:
+          {
+            char const *tmp_4;
+            if (flag->required) tmp_4 = ")"; else tmp_4 = ", optional)";
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s\t(array of strings%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_4); /* fprintf_va_22 */
+            break;
+          }
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_INT_ARRAY:
+          {
+            char const *tmp_5;
+            if (flag->required) tmp_5 = ")"; else tmp_5 = ", optional)";
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s\t(array of integers%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_5); /* fprintf_va_23 */
+            break;
+          }
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_DOUBLE_ARRAY:
+          {
+            char const *tmp_6;
+            if (flag->required) tmp_6 = ")"; else tmp_6 = ", optional)";
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s\t(array of floats%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_6); /* fprintf_va_24 */
+            break;
+          }
+          default: break;
+        }
+        if (flag->description) fprintf(__fc_stderr,"\t\t%s\n",
+                                       (char *)flag->description); /* fprintf_va_25 */
+        fprintf(__fc_stderr,"\n"); /* fprintf_va_26 */
+      }
+      i ++;
+    }
+  }
+  return;
+}
+
+void kgflags_set_custom_description(char const *description)
+{
+  _kgflags_g.custom_description = description;
+  return;
+}
+
+int kgflags_string_array_get_count(kgflags_string_array_t const *arr)
+{
+  int __retres;
+  __retres = arr->_count;
+  return __retres;
+}
+
+char const *kgflags_string_array_get_item(kgflags_string_array_t const *arr,
+                                          int at)
+{
+  char const *__retres;
+  if (at < 0) goto _LOR;
+  else 
+    if (at >= arr->_count) {
+      _LOR: {
+              __retres = (char const *)0;
+              goto return_label;
+            }
+    }
+  __retres = (char const *)*(arr->_items + at);
+  return_label: return __retres;
+}
+
+int kgflags_int_array_get_count(kgflags_int_array_t const *arr)
+{
+  int __retres;
+  __retres = arr->_count;
+  return __retres;
+}
+
+int kgflags_int_array_get_item(kgflags_int_array_t const *arr, int at)
+{
+  int __retres;
+  if (at < 0) goto _LOR;
+  else 
+    if (at >= arr->_count) {
+      _LOR: {
+              __retres = 0;
+              goto return_label;
+            }
+    }
+  char const *str = (char const *)*(arr->_items + at);
+  _Bool ok = (_Bool)0;
+  int res = _kgflags_parse_int(str,& ok);
+  if (! ok) {
+    __retres = 0;
+    goto return_label;
+  }
+  __retres = res;
+  return_label: return __retres;
+}
+
+int kgflags_double_array_get_count(kgflags_double_array_t const *arr)
+{
+  int __retres;
+  __retres = arr->_count;
+  return __retres;
+}
+
+double kgflags_double_array_get_item(kgflags_double_array_t const *arr,
+                                     int at)
+{
+  double __retres;
+  if (at < 0) goto _LOR;
+  else 
+    if (at >= arr->_count) {
+      _LOR: {
+              __retres = 0.0;
+              goto return_label;
+            }
+    }
+  char const *str = (char const *)*(arr->_items + at);
+  _Bool ok = (_Bool)0;
+  double res = _kgflags_parse_double(str,& ok);
+  if (! ok) {
+    __retres = 0.0;
+    goto return_label;
+  }
+  __retres = res;
+  return_label: return __retres;
+}
+
+int kgflags_get_non_flag_args_count(void)
+{
+  int __retres;
+  __retres = _kgflags_g.non_flag_count;
+  return __retres;
+}
+
+char const *kgflags_get_non_flag_arg(int at)
+{
+  char const *__retres;
+  if (at < 0) goto _LOR;
+  else 
+    if (at >= _kgflags_g.non_flag_count) {
+      _LOR: {
+              __retres = (char const *)0;
+              goto return_label;
+            }
+    }
+  __retres = _kgflags_g.non_flag_args[at];
+  return_label: return __retres;
+}
+
+static _Bool _kgflags_is_flag(char const *arg)
+{
+  _Bool __retres;
+  char const *tmp;
+  tmp = _kgflags_get_flag_name(arg);
+  __retres = (_Bool)(tmp != (char const *)0);
+  return __retres;
+}
+
+static char const *_kgflags_get_flag_name(char const *arg)
+{
+  char const *__retres;
+  size_t tmp_0;
+  int tmp_1;
+  unsigned long prefix_len = strlen(_kgflags_g.flag_prefix);
+  tmp_0 = strlen(arg);
+  ;
+  if (tmp_0 < prefix_len) {
+    __retres = (char const *)0;
+    goto return_label;
+  }
+  tmp_1 = strncmp(arg,_kgflags_g.flag_prefix,prefix_len);
+  if (tmp_1 != 0) {
+    __retres = (char const *)0;
+    goto return_label;
+  }
+  __retres = arg + prefix_len;
+  return_label: return __retres;
+}
+
+static void _kgflags_add_flag(_kgflags_flag_t flag)
+{
+  _kgflags_flag_t *tmp;
+  tmp = _kgflags_get_flag(flag.name,(_Bool *)0);
+  if (tmp != (_kgflags_flag_t *)0) {
+    _kgflags_add_error(KGFLAGS_ERROR_KIND_DUPLICATE_FLAG,flag.name,
+                       (char const *)0);
+    goto return_label;
+  }
+  if (_kgflags_g.flags_count >= 256) {
+    _kgflags_add_error(KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS,(char const *)0,
+                       (char const *)0);
+    goto return_label;
+  }
+  _kgflags_g.flags[_kgflags_g.flags_count] = flag;
+  (_kgflags_g.flags_count) ++;
+  return_label: return;
+}
+
+static _kgflags_flag_t *_kgflags_get_flag(char const *name,
+                                          _Bool *out_prefix_no)
+{
+  _kgflags_flag_t *__retres;
+  if (out_prefix_no) *out_prefix_no = (_Bool)0;
+  {
+    int i = 0;
+    while (i < _kgflags_g.flags_count) {
+      {
+        int tmp;
+        _kgflags_flag_t *flag = & _kgflags_g.flags[i];
+        tmp = strcmp(name,flag->name);
+        if (tmp == 0) {
+          __retres = flag;
+          goto return_label;
+        }
+        if (flag->kind == (unsigned int)KGFLAGS_FLAG_KIND_BOOL) {
+          char *tmp_1;
+          tmp_1 = strstr(name,"no-");
+          ;
+          if ((void *)tmp_1 == (void *)name) {
+            int tmp_0;
+            tmp_0 = strcmp(name + 3,flag->name);
+            if (tmp_0 == 0) {
+              if (out_prefix_no) *out_prefix_no = (_Bool)1;
+              __retres = flag;
+              goto return_label;
+            }
+          }
+        }
+      }
+      i ++;
+    }
+  }
+  __retres = (_kgflags_flag_t *)0;
+  return_label: return __retres;
+}
+
+static int _kgflags_parse_int(char const *str, _Bool *out_ok)
+{
+  int __retres;
+  *out_ok = (_Bool)0;
+  char *end = (char *)0;
+  long res_l = strtol(str,& end,10);
+  if ((void *)end == (void *)str) goto _LOR;
+  else 
+    if ((int)*end != '\000') goto _LOR;
+    else 
+      if (res_l > (long)2147483647) goto _LOR;
+      else 
+        if (res_l < (long)(-2147483647 - 1)) goto _LOR;
+        else 
+          if (res_l == -9223372036854775807L - 1L) goto _LOR_0;
+          else 
+            if (res_l == 9223372036854775807L) {
+              _LOR_0: ;
+              if (34 == __fc_errno) {
+                _LOR:
+                {
+                  *out_ok = (_Bool)0;
+                  __retres = 0;
+                  goto return_label;
+                }
+              }
+            }
+  *out_ok = (_Bool)1;
+  __retres = (int)res_l;
+  return_label: return __retres;
+}
+
+static double _kgflags_parse_double(char const *str, _Bool *out_ok)
+{
+  double __retres;
+  *out_ok = (_Bool)0;
+  char *end = (char *)0;
+  double res = strtod(str,& end);
+  if ((void *)end == (void *)str) goto _LOR;
+  else 
+    if ((int)*end != '\000') goto _LOR;
+    else 
+      if (res == - ((double)INFINITY)) goto _LOR_0;
+      else 
+        if (res == (double)INFINITY) {
+          _LOR_0: ;
+          if (34 == __fc_errno) {
+            _LOR: {
+                    *out_ok = (_Bool)0;
+                    __retres = 0.0;
+                    goto return_label;
+                  }
+          }
+        }
+  *out_ok = (_Bool)1;
+  __retres = res;
+  return_label: return __retres;
+}
+
+static void _kgflags_add_error(_kgflags_error_kind_t kind,
+                               char const *flag_name, char const *arg)
+{
+  _kgflags_error_t err;
+  err.kind = kind;
+  err.flag_name = flag_name;
+  err.arg = arg;
+  if (_kgflags_g.errors_count >= 512) goto return_label;
+  _kgflags_g.errors[_kgflags_g.errors_count] = err;
+  (_kgflags_g.errors_count) ++;
+  return_label: return;
+}
+
+static void _kgflags_assign_default_values(void)
+{
+  int i = 0;
+  while (i < _kgflags_g.flags_count) {
+    {
+      _kgflags_flag_t *flag = & _kgflags_g.flags[i];
+      if (flag->assigned) goto _LOR;
+      else 
+        if (flag->required) _LOR: goto __Cont;
+      switch (flag->kind) {
+        case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_STRING:
+        {
+          *(flag->result.string_value) = flag->default_value.string_value;
+          flag->assigned = (_Bool)1;
+          break;
+        }
+        case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_BOOL:
+        {
+          *(flag->result.bool_value) = flag->default_value.bool_value;
+          flag->assigned = (_Bool)1;
+          break;
+        }
+        case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_INT:
+        {
+          *(flag->result.int_value) = flag->default_value.int_value;
+          flag->assigned = (_Bool)1;
+          break;
+        }
+        case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_DOUBLE:
+        {
+          *(flag->result.double_value) = flag->default_value.double_value;
+          flag->assigned = (_Bool)1;
+          break;
+        }
+        default: break;
+      }
+    }
+    __Cont: i ++;
+  }
+  return;
+}
+
+static _Bool _kgflags_add_non_flag_arg(char const *arg)
+{
+  _Bool __retres;
+  if (_kgflags_g.non_flag_count >= 512) {
+    _kgflags_add_error(KGFLAGS_ERROR_KIND_TOO_MANY_NON_FLAG_ARGS,
+                       (char const *)0,(char const *)0);
+    __retres = (_Bool)0;
+    goto return_label;
+  }
+  _kgflags_g.non_flag_args[_kgflags_g.non_flag_count] = arg;
+  (_kgflags_g.non_flag_count) ++;
+  __retres = (_Bool)1;
+  return_label: return __retres;
+}
+
+static char const *_kgflags_consume_arg(void)
+{
+  char const *__retres;
+  if (_kgflags_g.arg_cursor >= _kgflags_g.argc) {
+    __retres = (char const *)0;
+    goto return_label;
+  }
+  char const *res = (char const *)*(_kgflags_g.argv + _kgflags_g.arg_cursor);
+  (_kgflags_g.arg_cursor) ++;
+  __retres = res;
+  return_label: return __retres;
+}
+
+static char const *_kgflags_peek_arg(void)
+{
+  char const *__retres;
+  if (_kgflags_g.arg_cursor >= _kgflags_g.argc) {
+    __retres = (char const *)0;
+    goto return_label;
+  }
+  __retres = (char const *)*(_kgflags_g.argv + _kgflags_g.arg_cursor);
+  return_label: return __retres;
+}
+
+static void _kgflags_parse_flag(_kgflags_flag_t *flag, _Bool prefix_no)
+{
+  switch (flag->kind) {
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_STRING:
+    {
+      char const *val = _kgflags_consume_arg();
+      if (! val) {
+        flag->error = (_Bool)1;
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_MISSING_VALUE,flag->name,
+                           (char const *)0);
+        goto return_label;
+      }
+      *(flag->result.string_value) = val;
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_BOOL:
+    {
+      *(flag->result.bool_value) = (_Bool)(! prefix_no);
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_INT:
+    {
+      char const *val_0 = _kgflags_consume_arg();
+      if (! val_0) {
+        flag->error = (_Bool)1;
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_MISSING_VALUE,flag->name,
+                           (char const *)0);
+        goto return_label;
+      }
+      _Bool ok = (_Bool)0;
+      int int_val = _kgflags_parse_int(val_0,& ok);
+      if (! ok) {
+        flag->error = (_Bool)1;
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_INT,flag->name,val_0);
+        goto return_label;
+      }
+      *(flag->result.int_value) = int_val;
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_DOUBLE:
+    {
+      char const *val_1 = _kgflags_consume_arg();
+      if (! val_1) {
+        flag->error = (_Bool)1;
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_MISSING_VALUE,flag->name,
+                           (char const *)0);
+        goto return_label;
+      }
+      _Bool ok_0 = (_Bool)0;
+      double double_val = _kgflags_parse_double(val_1,& ok_0);
+      if (! ok_0) {
+        flag->error = (_Bool)1;
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_DOUBLE,flag->name,
+                           val_1);
+        goto return_label;
+      }
+      *(flag->result.double_value) = double_val;
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_STRING_ARRAY:
+    {
+      int initial_cursor = _kgflags_g.arg_cursor;
+      int count = 0;
+      while (1) {
+        {
+          char const *val_2 = _kgflags_peek_arg();
+          if (val_2 == (char const *)0) goto _LOR;
+          else {
+            _Bool tmp_5;
+            tmp_5 = _kgflags_is_flag(val_2);
+            if (tmp_5) _LOR: break;
+          }
+          _kgflags_consume_arg();
+          count ++;
+        }
+      }
+      kgflags_string_array_t *arr = flag->result.string_array;
+      arr->_items = _kgflags_g.argv + initial_cursor;
+      arr->_count = count;
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_INT_ARRAY:
+    {
+      int initial_cursor_0 = _kgflags_g.arg_cursor;
+      int count_0 = 0;
+      _Bool all_args_ok = (_Bool)1;
+      while (1) {
+        {
+          char const *val_3 = _kgflags_peek_arg();
+          if (val_3 == (char const *)0) goto _LOR_0;
+          else {
+            _Bool tmp_7;
+            tmp_7 = _kgflags_is_flag(val_3);
+            if (tmp_7) _LOR_0: break;
+          }
+          _kgflags_consume_arg();
+          _Bool ok_1 = (_Bool)0;
+          _kgflags_parse_int(val_3,& ok_1);
+          if (! ok_1) {
+            flag->error = (_Bool)1;
+            _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_INT,flag->name,
+                               val_3);
+            all_args_ok = (_Bool)0;
+          }
+          count_0 ++;
+        }
+      }
+      kgflags_int_array_t *arr_0 = flag->result.int_array;
+      if (all_args_ok) {
+        arr_0->_items = _kgflags_g.argv + initial_cursor_0;
+        arr_0->_count = count_0;
+      }
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_DOUBLE_ARRAY:
+    {
+      int initial_cursor_1 = _kgflags_g.arg_cursor;
+      int count_1 = 0;
+      _Bool all_args_ok_0 = (_Bool)1;
+      while (1) {
+        {
+          char const *val_4 = _kgflags_peek_arg();
+          if (val_4 == (char const *)0) goto _LOR_1;
+          else {
+            _Bool tmp_9;
+            tmp_9 = _kgflags_is_flag(val_4);
+            if (tmp_9) _LOR_1: break;
+          }
+          _kgflags_consume_arg();
+          _Bool ok_2 = (_Bool)0;
+          _kgflags_parse_double(val_4,& ok_2);
+          if (! ok_2) {
+            flag->error = (_Bool)1;
+            _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_DOUBLE,flag->name,
+                               val_4);
+            all_args_ok_0 = (_Bool)0;
+          }
+          count_1 ++;
+        }
+      }
+      kgflags_double_array_t *arr_1 = flag->result.double_array;
+      if (all_args_ok_0) {
+        arr_1->_items = _kgflags_g.argv + initial_cursor_1;
+        arr_1->_count = count_1;
+      }
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    default: break;
+  }
+  return_label: return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_1(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param0 + (0 ..));
+ */
+int printf_va_2(char const * __restrict format, char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_3(char const * __restrict format, int param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_4(char const * __restrict format, double param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_5(char const * __restrict format, int param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param1 + (0 ..)), param0;
+ */
+int printf_va_6(char const * __restrict format, int param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_7(char const * __restrict format, int param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param1),
+            (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param1, param0;
+ */
+int printf_va_8(char const * __restrict format, int param0, int param1);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_9(char const * __restrict format, int param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param1),
+            (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param1, param0;
+ */
+int printf_va_10(char const * __restrict format, int param0, double param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            (indirect: __fc_stdout->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: param0);
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            *(param1 + (0 ..)), param0;
+ */
+int printf_va_11(char const * __restrict format, int param0, char *param1);
+
+int main(int argc, char **argv)
+{
+  int __retres;
+  kgflags_string_array_t string_arr;
+  kgflags_int_array_t int_arr;
+  kgflags_double_array_t double_arr;
+  _Bool tmp;
+  char const *tmp_0;
+  int tmp_1;
+  int tmp_4;
+  int tmp_7;
+  char const *string_val = (char const *)0;
+  kgflags_string("string","lorem","String flag.",(_Bool)1,& string_val);
+  _Bool bool_val = (_Bool)0;
+  kgflags_bool("bool",(_Bool)0,"Boolean flag.",(_Bool)1,& bool_val);
+  int int_val = 0;
+  kgflags_int("int",0,"Integer flag.",(_Bool)1,& int_val);
+  double double_val = (double)0;
+  kgflags_double("double",0.0,"Double flag.",(_Bool)1,& double_val);
+  kgflags_string_array("string-array","String array flag.",(_Bool)1,
+                       & string_arr);
+  kgflags_int_array("int-array","Int array flag.",(_Bool)1,& int_arr);
+  kgflags_double_array("double-array","Double array flag.",(_Bool)1,
+                       & double_arr);
+  kgflags_set_custom_description("Usage of fullapi [-FLAGS]:");
+  kgflags_set_prefix("-");
+  tmp = kgflags_parse(argc,argv);
+  if (! tmp) {
+    kgflags_print_errors();
+    kgflags_print_usage();
+    __retres = 1;
+    goto return_label;
+  }
+  printf("string_val: %s\n",(char *)string_val); /* printf_va_1 */
+  if (bool_val) tmp_0 = "true"; else tmp_0 = "false";
+  printf("bool_val: %s\n",(char *)tmp_0); /* printf_va_2 */
+  printf("int_val: %d\n",int_val); /* printf_va_3 */
+  printf("double_val: %f\n",double_val); /* printf_va_4 */
+  tmp_1 = kgflags_string_array_get_count((kgflags_string_array_t const *)(& string_arr));
+  printf("string-arr count: %d\n",tmp_1); /* printf_va_5 */
+  {
+    int i = 0;
+    while (1) {
+      int tmp_3;
+      tmp_3 = kgflags_string_array_get_count((kgflags_string_array_t const *)(& string_arr));
+      ;
+      if (! (i < tmp_3)) break;
+      {
+        char const *tmp_2;
+        tmp_2 = kgflags_string_array_get_item((kgflags_string_array_t const *)(& string_arr),
+                                              i);
+        ;
+        printf("string-arr [%d]\n: %s",i,(char *)tmp_2); /* printf_va_6 */
+      }
+      i ++;
+    }
+  }
+  tmp_4 = kgflags_int_array_get_count((kgflags_int_array_t const *)(& int_arr));
+  printf("int-arr count: %d\n",tmp_4); /* printf_va_7 */
+  {
+    int i_0 = 0;
+    while (1) {
+      int tmp_6;
+      tmp_6 = kgflags_int_array_get_count((kgflags_int_array_t const *)(& int_arr));
+      ;
+      if (! (i_0 < tmp_6)) break;
+      {
+        int tmp_5;
+        tmp_5 = kgflags_int_array_get_item((kgflags_int_array_t const *)(& int_arr),
+                                           i_0);
+        ;
+        printf("int-arr [%d]: %d\n",i_0,tmp_5); /* printf_va_8 */
+      }
+      i_0 ++;
+    }
+  }
+  tmp_7 = kgflags_double_array_get_count((kgflags_double_array_t const *)(& double_arr));
+  printf("double-arr count: %d\n",tmp_7); /* printf_va_9 */
+  {
+    int i_1 = 0;
+    while (1) {
+      int tmp_9;
+      tmp_9 = kgflags_double_array_get_count((kgflags_double_array_t const *)(& double_arr));
+      ;
+      if (! (i_1 < tmp_9)) break;
+      {
+        double tmp_8;
+        tmp_8 = kgflags_double_array_get_item((kgflags_double_array_t const *)(& double_arr),
+                                              i_1);
+        ;
+        printf("double-arr [%d]: %1.4g\n",i_1,tmp_8); /* printf_va_10 */
+      }
+      i_1 ++;
+    }
+  }
+  int non_flag_count = kgflags_get_non_flag_args_count();
+  {
+    int i_2 = 0;
+    while (i_2 < non_flag_count) {
+      {
+        char const *tmp_11;
+        tmp_11 = kgflags_get_non_flag_arg(i_2);
+        ;
+        printf("Non-flag arguments [%d] = %s\n",i_2,(char *)tmp_11); /* printf_va_11 */
+      }
+      i_2 ++;
+    }
+  }
+  __retres = 0;
+  return_label: return __retres;
+}
+
+
diff --git a/kgflags/.frama-c/kgflags-full_api.parse/metrics.log b/kgflags/.frama-c/kgflags-full_api.parse/metrics.log
new file mode 100644
index 000000000..70089ef87
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-full_api.parse/metrics.log
@@ -0,0 +1,50 @@
+[metrics] Defined functions (34)
+======================
+ _kgflags_add_error (14 calls); _kgflags_add_flag (7 calls);
+ _kgflags_add_non_flag_arg (1 call); _kgflags_assign_default_values (1 call);
+ _kgflags_consume_arg (7 calls); _kgflags_get_flag (2 calls);
+ _kgflags_get_flag_name (2 calls); _kgflags_is_flag (4 calls);
+ _kgflags_parse_double (3 calls); _kgflags_parse_flag (1 call);
+ _kgflags_parse_int (3 calls); _kgflags_peek_arg (3 calls);
+ eva_main (0 call); kgflags_bool (1 call); kgflags_double (1 call);
+ kgflags_double_array (1 call); kgflags_double_array_get_count (2 calls);
+ kgflags_double_array_get_item (1 call); kgflags_get_non_flag_arg (1 call);
+ kgflags_get_non_flag_args_count (1 call); kgflags_int (1 call);
+ kgflags_int_array (1 call); kgflags_int_array_get_count (2 calls);
+ kgflags_int_array_get_item (1 call); kgflags_parse (1 call);
+ kgflags_print_errors (1 call); kgflags_print_usage (1 call);
+ kgflags_set_custom_description (1 call); kgflags_set_prefix (1 call);
+ kgflags_string (1 call); kgflags_string_array (1 call);
+ kgflags_string_array_get_count (2 calls);
+ kgflags_string_array_get_item (1 call); main (1 call); 
+
+Specified-only functions (0)
+============================
+ 
+
+Undefined and unspecified functions (0)
+=======================================
+ 
+
+'Extern' global variables (0)
+=============================
+ 
+
+Potential entry points (1)
+==========================
+ eva_main; 
+
+Global metrics
+============== 
+Sloc = 736
+Decision point = 118
+Global variables = 1
+If = 90
+Loop = 14
+Goto = 44
+Assignment = 269
+Exit point = 34
+Function = 34
+Function call = 127
+Pointer dereferencing = 140
+Cyclomatic complexity = 152
diff --git a/kgflags/.frama-c/kgflags-full_api.parse/warnings.log b/kgflags/.frama-c/kgflags-full_api.parse/warnings.log
new file mode 100644
index 000000000..e69de29bb
diff --git a/kgflags/.frama-c/kgflags-simple.eva/alarms.csv b/kgflags/.frama-c/kgflags-simple.eva/alarms.csv
new file mode 100644
index 000000000..fcd06d6b7
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-simple.eva/alarms.csv
@@ -0,0 +1,36 @@
+directory	file	line	function	property kind	status	property
+.	kgflags.h	402	kgflags_print_errors	initialization	Unknown	\initialized(&err->kind)
+.	kgflags.h	404	fprintf_va_1	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	404	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	404	kgflags_print_errors	precondition of fprintf_va_1	Unknown	valid_read_string(param1)
+.	kgflags.h	408	fprintf_va_2	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	408	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	408	kgflags_print_errors	precondition of fprintf_va_2	Unknown	valid_read_string(param1)
+.	kgflags.h	412	fprintf_va_3	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	412	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	412	kgflags_print_errors	precondition of fprintf_va_3	Unknown	valid_read_string(param1)
+.	kgflags.h	416	fprintf_va_4	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	416	fprintf_va_4	precondition	Unknown	valid_read_string(param2)
+.	kgflags.h	416	kgflags_print_errors	initialization	Unknown	\initialized(&err->arg)
+.	kgflags.h	416	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	416	kgflags_print_errors	precondition of fprintf_va_4	Unknown	valid_read_string(param1)
+.	kgflags.h	416	kgflags_print_errors	precondition of fprintf_va_4	Unknown	valid_read_string(param2)
+.	kgflags.h	420	fprintf_va_5	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	420	fprintf_va_5	precondition	Unknown	valid_read_string(param2)
+.	kgflags.h	420	kgflags_print_errors	initialization	Unknown	\initialized(&err->arg)
+.	kgflags.h	420	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	420	kgflags_print_errors	precondition of fprintf_va_5	Unknown	valid_read_string(param1)
+.	kgflags.h	420	kgflags_print_errors	precondition of fprintf_va_5	Unknown	valid_read_string(param2)
+.	kgflags.h	432	fprintf_va_8	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	432	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	432	kgflags_print_errors	precondition of fprintf_va_8	Unknown	valid_read_string(param1)
+.	kgflags.h	436	fprintf_va_9	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	436	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	436	kgflags_print_errors	precondition of fprintf_va_9	Unknown	valid_read_string(param1)
+.	kgflags.h	440	fprintf_va_10	precondition	Unknown	valid_read_string(param1)
+.	kgflags.h	440	kgflags_print_errors	initialization	Unknown	\initialized(&err->flag_name)
+.	kgflags.h	440	kgflags_print_errors	precondition of fprintf_va_10	Unknown	valid_read_string(param1)
+.	kgflags.h	608	_kgflags_get_flag	precondition of strcmp	Unknown	valid_string_s1: valid_read_string(s1)
+FRAMAC_SHARE/libc	stdio.h	336	puts	precondition	Unknown	valid_string_s: valid_read_string(s)
+FRAMAC_SHARE/libc	string.h	137	strcmp	precondition	Unknown	valid_string_s1: valid_read_string(s1)
+examples	simple.c	12	main	precondition of puts	Unknown	valid_string_s: valid_read_string(s)
diff --git a/kgflags/.frama-c/kgflags-simple.eva/metrics.log b/kgflags/.frama-c/kgflags-simple.eva/metrics.log
new file mode 100644
index 000000000..ccf0cef09
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-simple.eva/metrics.log
@@ -0,0 +1,35 @@
+[metrics] Eva coverage statistics
+=======================
+Syntactically reachable functions = 18 (out of 34)
+Semantically reached functions = 15
+Coverage estimation = 83.3% 
+
+Unreached functions (3) =
+  <kgflags.h>: _kgflags_parse_double; _kgflags_parse_int; _kgflags_peek_arg;
+[metrics] References to non-analyzed functions
+------------------------------------
+Function _kgflags_parse_flag calls _kgflags_parse_int (at kgflags.h:747)
+Function _kgflags_parse_flag calls _kgflags_parse_double (at kgflags.h:765)
+Function _kgflags_parse_flag calls _kgflags_peek_arg (at kgflags.h:779)
+Function _kgflags_parse_flag calls _kgflags_peek_arg (at kgflags.h:797)
+Function _kgflags_parse_flag calls _kgflags_parse_int (at kgflags.h:803)
+Function _kgflags_parse_flag calls _kgflags_peek_arg (at kgflags.h:824)
+Function _kgflags_parse_flag calls _kgflags_parse_double (at kgflags.h:830)
+[metrics] Statements analyzed by Eva
+--------------------------
+474 stmts in analyzed functions, 240 stmts analyzed (50.6%)
+_kgflags_add_error: 9 stmts out of 9 (100.0%)
+_kgflags_add_non_flag_arg: 9 stmts out of 9 (100.0%)
+_kgflags_consume_arg: 8 stmts out of 8 (100.0%)
+_kgflags_get_flag_name: 15 stmts out of 15 (100.0%)
+_kgflags_is_flag: 3 stmts out of 3 (100.0%)
+eva_main: 13 stmts out of 13 (100.0%)
+kgflags_print_errors: 40 stmts out of 40 (100.0%)
+kgflags_string: 11 stmts out of 11 (100.0%)
+main: 12 stmts out of 12 (100.0%)
+kgflags_parse: 45 stmts out of 48 (93.8%)
+_kgflags_get_flag: 18 stmts out of 29 (62.1%)
+_kgflags_add_flag: 6 stmts out of 12 (50.0%)
+_kgflags_assign_default_values: 13 stmts out of 31 (41.9%)
+kgflags_print_usage: 26 stmts out of 110 (23.6%)
+_kgflags_parse_flag: 12 stmts out of 124 (9.7%)
diff --git a/kgflags/.frama-c/kgflags-simple.eva/nonterm.log b/kgflags/.frama-c/kgflags-simple.eva/nonterm.log
new file mode 100644
index 000000000..e69de29bb
diff --git a/kgflags/.frama-c/kgflags-simple.eva/warnings.log b/kgflags/.frama-c/kgflags-simple.eva/warnings.log
new file mode 100644
index 000000000..a4169e610
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-simple.eva/warnings.log
@@ -0,0 +1,5 @@
+fc_stubs.c:21:[eva:locals-escaping] warning: locals {to_print} escaping the scope of main through _kgflags_g
+[eva:garbled-mix] warning: Garbled mix generated during analysis:
+{{ garbled mix of &{argv1; argv2; argv3; argv4}
+  (origin: Misaligned {kgflags.h:657}) }}
+{{ garbled mix of &{"to-print"} (origin: Misaligned {kgflags.h:657}) }}
diff --git a/kgflags/.frama-c/kgflags-simple.parse/framac.ast b/kgflags/.frama-c/kgflags-simple.parse/framac.ast
new file mode 100644
index 000000000..abe6da898
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-simple.parse/framac.ast
@@ -0,0 +1,1535 @@
+/* Generated by Frama-C */
+#include "__fc_builtin.h"
+#include "errno.h"
+#include "math.h"
+#include "stdarg.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "strings.h"
+struct kgflags_string_array {
+   char **_items ;
+   int _count ;
+};
+typedef struct kgflags_string_array kgflags_string_array_t;
+struct kgflags_int_array {
+   char **_items ;
+   int _count ;
+};
+typedef struct kgflags_int_array kgflags_int_array_t;
+struct kgflags_double_array {
+   char **_items ;
+   int _count ;
+};
+typedef struct kgflags_double_array kgflags_double_array_t;
+enum _kgflags_flag_kind {
+    KGFLAGS_FLAG_KIND_NONE = 0,
+    KGFLAGS_FLAG_KIND_STRING = 1,
+    KGFLAGS_FLAG_KIND_BOOL = 2,
+    KGFLAGS_FLAG_KIND_INT = 3,
+    KGFLAGS_FLAG_KIND_DOUBLE = 4,
+    KGFLAGS_FLAG_KIND_STRING_ARRAY = 5,
+    KGFLAGS_FLAG_KIND_INT_ARRAY = 6,
+    KGFLAGS_FLAG_KIND_DOUBLE_ARRAY = 7
+};
+typedef enum _kgflags_flag_kind _kgflags_flag_kind_t;
+union __anonunion_default_value_1 {
+   char const *string_value ;
+   _Bool bool_value ;
+   int int_value ;
+   double double_value ;
+};
+union __anonunion_result_2 {
+   char const **string_value ;
+   _Bool *bool_value ;
+   int *int_value ;
+   double *double_value ;
+   kgflags_string_array_t *string_array ;
+   kgflags_int_array_t *int_array ;
+   kgflags_double_array_t *double_array ;
+};
+struct _kgflags_flag {
+   char const *name ;
+   char const *description ;
+   union __anonunion_default_value_1 default_value ;
+   union __anonunion_result_2 result ;
+   _Bool assigned ;
+   _Bool error ;
+   _Bool required ;
+   _kgflags_flag_kind_t kind ;
+};
+typedef struct _kgflags_flag _kgflags_flag_t;
+enum _kgflags_error_kind {
+    KGFLAGS_ERROR_KIND_NONE = 0,
+    KGFLAGS_ERROR_KIND_MISSING_VALUE = 1,
+    KGFLAGS_ERROR_KIND_UNKNOWN_FLAG = 2,
+    KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG = 3,
+    KGFLAGS_ERROR_KIND_INVALID_INT = 4,
+    KGFLAGS_ERROR_KIND_INVALID_DOUBLE = 5,
+    KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS = 6,
+    KGFLAGS_ERROR_KIND_TOO_MANY_NON_FLAG_ARGS = 7,
+    KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT = 8,
+    KGFLAGS_ERROR_KIND_DUPLICATE_FLAG = 9,
+    KGFLAGS_ERROR_KIND_PREFIX_NO = 10
+};
+typedef enum _kgflags_error_kind _kgflags_error_kind_t;
+struct _kgflags_error {
+   char const *flag_name ;
+   char const *arg ;
+   _kgflags_error_kind_t kind ;
+};
+typedef struct _kgflags_error _kgflags_error_t;
+struct __anonstruct__kgflags_g_3 {
+   int flags_count ;
+   _kgflags_flag_t flags[256] ;
+   int non_flag_count ;
+   char const *non_flag_args[512] ;
+   int errors_count ;
+   _kgflags_error_t errors[512] ;
+   char const *flag_prefix ;
+   int arg_cursor ;
+   int argc ;
+   char **argv ;
+   char const *custom_description ;
+};
+int main(int argc, char **argv);
+
+int eva_main(void)
+{
+  char argv0[256];
+  char argv1[256];
+  char argv2[256];
+  char argv3[256];
+  char argv4[256];
+  int tmp_0;
+  int argc = Frama_C_interval(0,5);
+  char *argv[6] = {argv0, argv1, argv2, argv3, argv4, (char *)0};
+  {
+    int i = 0;
+    /*@ loop unroll 5; */
+    while (i < 5) {
+      Frama_C_make_unknown(argv[i],(unsigned long)255);
+      *(argv[i] + 255) = (char)0;
+      i ++;
+    }
+  }
+  tmp_0 = main(argc,argv);
+  return tmp_0;
+}
+
+void kgflags_string(char const *name, char const *default_value,
+                    char const *description, _Bool required,
+                    char const **out_res);
+
+void kgflags_bool(char const *name, _Bool default_value,
+                  char const *description, _Bool required, _Bool *out_res);
+
+void kgflags_int(char const *name, int default_value,
+                 char const *description, _Bool required, int *out_res);
+
+void kgflags_double(char const *name, double default_value,
+                    char const *description, _Bool required, double *out_res);
+
+void kgflags_string_array(char const *name, char const *description,
+                          _Bool required, kgflags_string_array_t *out_arr);
+
+void kgflags_int_array(char const *name, char const *description,
+                       _Bool required, kgflags_int_array_t *out_arr);
+
+void kgflags_double_array(char const *name, char const *description,
+                          _Bool required, kgflags_double_array_t *out_arr);
+
+void kgflags_set_prefix(char const *prefix);
+
+_Bool kgflags_parse(int argc, char **argv);
+
+void kgflags_print_errors(void);
+
+void kgflags_print_usage(void);
+
+void kgflags_set_custom_description(char const *description);
+
+int kgflags_string_array_get_count(kgflags_string_array_t const *arr);
+
+char const *kgflags_string_array_get_item(kgflags_string_array_t const *arr,
+                                          int at);
+
+int kgflags_int_array_get_count(kgflags_int_array_t const *arr);
+
+int kgflags_int_array_get_item(kgflags_int_array_t const *arr, int at);
+
+int kgflags_double_array_get_count(kgflags_double_array_t const *arr);
+
+double kgflags_double_array_get_item(kgflags_double_array_t const *arr,
+                                     int at);
+
+int kgflags_get_non_flag_args_count(void);
+
+char const *kgflags_get_non_flag_arg(int at);
+
+static _Bool _kgflags_is_flag(char const *arg);
+
+static char const *_kgflags_get_flag_name(char const *arg);
+
+static void _kgflags_add_flag(_kgflags_flag_t flag);
+
+static _kgflags_flag_t *_kgflags_get_flag(char const *name,
+                                          _Bool *out_prefix_no);
+
+static int _kgflags_parse_int(char const *str, _Bool *out_ok);
+
+static double _kgflags_parse_double(char const *str, _Bool *out_ok);
+
+static void _kgflags_add_error(_kgflags_error_kind_t kind,
+                               char const *flag_name, char const *arg);
+
+static void _kgflags_assign_default_values(void);
+
+static _Bool _kgflags_add_non_flag_arg(char const *arg);
+
+static char const *_kgflags_consume_arg(void);
+
+static char const *_kgflags_peek_arg(void);
+
+static void _kgflags_parse_flag(_kgflags_flag_t *flag, _Bool prefix_no);
+
+static struct __anonstruct__kgflags_g_3 _kgflags_g;
+void kgflags_string(char const *name, char const *default_value,
+                    char const *description, _Bool required,
+                    char const **out_res)
+{
+  _kgflags_flag_t flag;
+  *out_res = (char const *)0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_STRING;
+  flag.name = name;
+  flag.default_value.string_value = default_value;
+  flag.description = description;
+  flag.required = required;
+  flag.result.string_value = out_res;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_bool(char const *name, _Bool default_value,
+                  char const *description, _Bool required, _Bool *out_res)
+{
+  char *tmp;
+  _kgflags_flag_t flag;
+  *out_res = (_Bool)0;
+  tmp = strstr(name,"no-");
+  ;
+  if ((void *)tmp == (void *)name) {
+    _kgflags_add_error(KGFLAGS_ERROR_KIND_PREFIX_NO,name,(char const *)0);
+    goto return_label;
+  }
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_BOOL;
+  flag.name = name;
+  flag.default_value.bool_value = default_value;
+  flag.description = description;
+  flag.required = required;
+  flag.result.bool_value = out_res;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return_label: return;
+}
+
+void kgflags_int(char const *name, int default_value,
+                 char const *description, _Bool required, int *out_res)
+{
+  _kgflags_flag_t flag;
+  *out_res = 0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_INT;
+  flag.name = name;
+  flag.default_value.int_value = default_value;
+  flag.description = description;
+  flag.required = required;
+  flag.result.int_value = out_res;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_double(char const *name, double default_value,
+                    char const *description, _Bool required, double *out_res)
+{
+  _kgflags_flag_t flag;
+  *out_res = 0.0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_DOUBLE;
+  flag.name = name;
+  flag.default_value.double_value = default_value;
+  flag.description = description;
+  flag.required = required;
+  flag.result.double_value = out_res;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_string_array(char const *name, char const *description,
+                          _Bool required, kgflags_string_array_t *out_arr)
+{
+  _kgflags_flag_t flag;
+  out_arr->_items = (char **)0;
+  out_arr->_count = 0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_STRING_ARRAY;
+  flag.name = name;
+  flag.description = description;
+  flag.required = required;
+  flag.result.string_array = out_arr;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_int_array(char const *name, char const *description,
+                       _Bool required, kgflags_int_array_t *out_arr)
+{
+  _kgflags_flag_t flag;
+  out_arr->_items = (char **)0;
+  out_arr->_count = 0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_INT_ARRAY;
+  flag.name = name;
+  flag.description = description;
+  flag.required = required;
+  flag.result.int_array = out_arr;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_double_array(char const *name, char const *description,
+                          _Bool required, kgflags_double_array_t *out_arr)
+{
+  _kgflags_flag_t flag;
+  out_arr->_items = (char **)0;
+  out_arr->_count = 0;
+  memset((void *)(& flag),0,sizeof(_kgflags_flag_t));
+  flag.kind = KGFLAGS_FLAG_KIND_DOUBLE_ARRAY;
+  flag.name = name;
+  flag.description = description;
+  flag.required = required;
+  flag.result.double_array = out_arr;
+  flag.assigned = (_Bool)0;
+  _kgflags_add_flag(flag);
+  return;
+}
+
+void kgflags_set_prefix(char const *prefix)
+{
+  _kgflags_g.flag_prefix = prefix;
+  return;
+}
+
+_Bool kgflags_parse(int argc, char **argv)
+{
+  _Bool __retres;
+  _kgflags_g.argc = argc;
+  _kgflags_g.argv = argv;
+  _kgflags_g.arg_cursor = 1;
+  if (_kgflags_g.flag_prefix == (char const *)0) _kgflags_g.flag_prefix = "--";
+  if (_kgflags_g.errors_count > 0) {
+    __retres = (_Bool)0;
+    goto return_label;
+  }
+  char const *arg = (char const *)0;
+  while (1) {
+    arg = _kgflags_consume_arg();
+    if (! (arg != (char const *)0)) break;
+    {
+      _kgflags_flag_t *flag = (_kgflags_flag_t *)0;
+      _Bool is_flag = _kgflags_is_flag(arg);
+      _Bool prefix_no = (_Bool)0;
+      if (is_flag) {
+        char const *flag_name = _kgflags_get_flag_name(arg);
+        flag = _kgflags_get_flag(flag_name,& prefix_no);
+        if (flag == (_kgflags_flag_t *)0) {
+          _kgflags_add_error(KGFLAGS_ERROR_KIND_UNKNOWN_FLAG,flag_name,
+                             (char const *)0);
+          continue;
+        }
+      }
+      else {
+        _kgflags_add_non_flag_arg(arg);
+        continue;
+      }
+      if (flag->assigned) _kgflags_add_error(KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT,
+                                             flag->name,(char const *)0);
+      _kgflags_parse_flag(flag,prefix_no);
+    }
+  }
+  _kgflags_assign_default_values();
+  {
+    int i = 0;
+    while (i < _kgflags_g.flags_count) {
+      {
+        _kgflags_flag_t *flag_0 = & _kgflags_g.flags[i];
+        if (flag_0->required) 
+          if (! flag_0->assigned) 
+            if (! flag_0->error) _kgflags_add_error(KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG,
+                                                    flag_0->name,
+                                                    (char const *)0);
+      }
+      i ++;
+    }
+  }
+  if (_kgflags_g.errors_count > 0) {
+    __retres = (_Bool)0;
+    goto return_label;
+  }
+  __retres = (_Bool)1;
+  return_label: return __retres;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_1(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_2(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_3(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_4(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_5(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+ */
+int fprintf_va_6(FILE * __restrict stream, char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+ */
+int fprintf_va_7(FILE * __restrict stream, char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_8(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_9(FILE * __restrict stream, char const * __restrict format,
+                 char *param0, char *param1);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param1 + (0 ..))),
+            (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_10(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1);
+
+void kgflags_print_errors(void)
+{
+  int i = 0;
+  while (i < _kgflags_g.errors_count) {
+    {
+      _kgflags_error_t *err = & _kgflags_g.errors[i];
+      switch (err->kind) {
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_MISSING_VALUE:
+        {
+          fprintf(__fc_stderr,"Missing value for flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_1 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_UNKNOWN_FLAG:
+        {
+          fprintf(__fc_stderr,"Unrecognized flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_2 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG:
+        {
+          fprintf(__fc_stderr,"Unassigned required flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_3 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_INVALID_INT:
+        {
+          fprintf(__fc_stderr,
+                  "Invalid value for flag: %s%s (got %s, expected integer)\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name,
+                  (char *)err->arg); /* fprintf_va_4 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_INVALID_DOUBLE:
+        {
+          fprintf(__fc_stderr,
+                  "Invalid value for flag: %s%s (got %s, expected number)\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name,
+                  (char *)err->arg); /* fprintf_va_5 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS:
+        {
+          fprintf(__fc_stderr,"Too many flags declared."); /* fprintf_va_6 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_TOO_MANY_NON_FLAG_ARGS:
+        {
+          fprintf(__fc_stderr,
+                  "Too many non-flag arguments passed to program."); /* fprintf_va_7 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT:
+        {
+          fprintf(__fc_stderr,"Multiple assignment of flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_8 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_DUPLICATE_FLAG:
+        {
+          fprintf(__fc_stderr,"Redeclaration of flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_9 */
+          break;
+        }
+        case (_kgflags_error_kind_t)KGFLAGS_ERROR_KIND_PREFIX_NO:
+        {
+          fprintf(__fc_stderr,
+                  "Used \"no-\" prefix when declaring boolean flag: %s%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)err->flag_name); /* fprintf_va_10 */
+          break;
+        }
+        default: break;
+      }
+    }
+    i ++;
+  }
+  return;
+}
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param0 + (0 ..));
+ */
+int fprintf_va_11(FILE * __restrict stream, char const * __restrict format,
+                  char *param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param0 + (0 ..));
+ */
+int fprintf_va_12(FILE * __restrict stream, char const * __restrict format,
+                  char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+ */
+int fprintf_va_13(FILE * __restrict stream, char const * __restrict format);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_14(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param0 + (0 ..));
+ */
+int fprintf_va_15(FILE * __restrict stream, char const * __restrict format,
+                  char *param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param4);
+    requires valid_read_string(param3);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param4 + (0 ..))),
+            (indirect: *(param3 + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param4 + (0 ..)),
+            *(param3 + (0 ..)), *(param2 + (0 ..)), *(param1 + (0 ..)),
+            *(param0 + (0 ..));
+ */
+int fprintf_va_16(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2, char *param3,
+                  char *param4);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param0 + (0 ..));
+ */
+int fprintf_va_17(FILE * __restrict stream, char const * __restrict format,
+                  char *param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_18(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), param0;
+ */
+int fprintf_va_19(FILE * __restrict stream, char const * __restrict format,
+                  int param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_20(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: param0);
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), param0;
+ */
+int fprintf_va_21(FILE * __restrict stream, char const * __restrict format,
+                  double param0);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_22(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_23(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param2);
+    requires valid_read_string(param1);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param2 + (0 ..))),
+            (indirect: *(param1 + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param2 + (0 ..)),
+            *(param1 + (0 ..)), *(param0 + (0 ..));
+ */
+int fprintf_va_24(FILE * __restrict stream, char const * __restrict format,
+                  char *param0, char *param1, char *param2);
+
+/*@ requires valid_read_string(format);
+    requires valid_read_string(param0);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..))), (indirect: *(param0 + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..))), *(param0 + (0 ..));
+ */
+int fprintf_va_25(FILE * __restrict stream, char const * __restrict format,
+                  char *param0);
+
+/*@ requires valid_read_string(format);
+    assigns \result, stream->__fc_FILE_data;
+    assigns \result
+      \from (indirect: stream->__fc_FILE_id),
+            (indirect: stream->__fc_FILE_data),
+            (indirect: *(format + (0 ..)));
+    assigns stream->__fc_FILE_data
+      \from (indirect: stream->__fc_FILE_id), stream->__fc_FILE_data,
+            (indirect: *(format + (0 ..)));
+ */
+int fprintf_va_26(FILE * __restrict stream, char const * __restrict format);
+
+void kgflags_print_usage(void)
+{
+  if (_kgflags_g.custom_description == (char const *)0) fprintf(__fc_stderr,
+                                                                "Usage of %s:\n",
+                                                                *(_kgflags_g.argv + 0)); /* fprintf_va_11 */
+  else fprintf(__fc_stderr,"%s\n",(char *)_kgflags_g.custom_description); /* fprintf_va_12 */
+  fprintf(__fc_stderr,"Flags:\n"); /* fprintf_va_13 */
+  {
+    int i = 0;
+    while (i < _kgflags_g.flags_count) {
+      {
+        _kgflags_flag_t *flag = & _kgflags_g.flags[i];
+        switch (flag->kind) {
+          char const *tmp;
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_STRING:
+          { /* sequence */
+            if (flag->required) tmp = ")"; else tmp = ", optional)";
+            ;
+            ;
+            ;
+          }
+          fprintf(__fc_stderr,"\t%s%s\t(string%s\n",
+                  (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                  (char *)tmp); /* fprintf_va_14 */
+          if (! flag->required) fprintf(__fc_stderr,"\t\tDefault: %s\n",
+                                        (char *)flag->default_value.string_value); /* fprintf_va_15 */
+          break;
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_BOOL:
+          {
+            char const *tmp_0;
+            if (flag->required) tmp_0 = ")"; else tmp_0 = ", optional)";
+            ;
+            ;
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s, %sno-%s\t(boolean%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_0); /* fprintf_va_16 */
+            if (! flag->required) {
+              char const *tmp_1;
+              if (flag->default_value.bool_value) tmp_1 = "True";
+              else tmp_1 = "False";
+              ;
+              fprintf(__fc_stderr,"\t\tDefault: %s\n",(char *)tmp_1); /* fprintf_va_17 */
+            }
+            break;
+          }
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_INT:
+          {
+            char const *tmp_2;
+            if (flag->required) tmp_2 = ")"; else tmp_2 = ", optional)";
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s\t(integer%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_2); /* fprintf_va_18 */
+            if (! flag->required) fprintf(__fc_stderr,"\t\tDefault: %d\n",
+                                          flag->default_value.int_value); /* fprintf_va_19 */
+            break;
+          }
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_DOUBLE:
+          {
+            char const *tmp_3;
+            if (flag->required) tmp_3 = ")"; else tmp_3 = ", optional)";
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s\t(float%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_3); /* fprintf_va_20 */
+            if (! flag->required) fprintf(__fc_stderr,"\t\tDefault: %1.4g\n",
+                                          flag->default_value.double_value); /* fprintf_va_21 */
+            break;
+          }
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_STRING_ARRAY:
+          {
+            char const *tmp_4;
+            if (flag->required) tmp_4 = ")"; else tmp_4 = ", optional)";
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s\t(array of strings%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_4); /* fprintf_va_22 */
+            break;
+          }
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_INT_ARRAY:
+          {
+            char const *tmp_5;
+            if (flag->required) tmp_5 = ")"; else tmp_5 = ", optional)";
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s\t(array of integers%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_5); /* fprintf_va_23 */
+            break;
+          }
+          case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_DOUBLE_ARRAY:
+          {
+            char const *tmp_6;
+            if (flag->required) tmp_6 = ")"; else tmp_6 = ", optional)";
+            ;
+            ;
+            ;
+            fprintf(__fc_stderr,"\t%s%s\t(array of floats%s\n",
+                    (char *)_kgflags_g.flag_prefix,(char *)flag->name,
+                    (char *)tmp_6); /* fprintf_va_24 */
+            break;
+          }
+          default: break;
+        }
+        if (flag->description) fprintf(__fc_stderr,"\t\t%s\n",
+                                       (char *)flag->description); /* fprintf_va_25 */
+        fprintf(__fc_stderr,"\n"); /* fprintf_va_26 */
+      }
+      i ++;
+    }
+  }
+  return;
+}
+
+void kgflags_set_custom_description(char const *description)
+{
+  _kgflags_g.custom_description = description;
+  return;
+}
+
+int kgflags_string_array_get_count(kgflags_string_array_t const *arr)
+{
+  int __retres;
+  __retres = arr->_count;
+  return __retres;
+}
+
+char const *kgflags_string_array_get_item(kgflags_string_array_t const *arr,
+                                          int at)
+{
+  char const *__retres;
+  if (at < 0) goto _LOR;
+  else 
+    if (at >= arr->_count) {
+      _LOR: {
+              __retres = (char const *)0;
+              goto return_label;
+            }
+    }
+  __retres = (char const *)*(arr->_items + at);
+  return_label: return __retres;
+}
+
+int kgflags_int_array_get_count(kgflags_int_array_t const *arr)
+{
+  int __retres;
+  __retres = arr->_count;
+  return __retres;
+}
+
+int kgflags_int_array_get_item(kgflags_int_array_t const *arr, int at)
+{
+  int __retres;
+  if (at < 0) goto _LOR;
+  else 
+    if (at >= arr->_count) {
+      _LOR: {
+              __retres = 0;
+              goto return_label;
+            }
+    }
+  char const *str = (char const *)*(arr->_items + at);
+  _Bool ok = (_Bool)0;
+  int res = _kgflags_parse_int(str,& ok);
+  if (! ok) {
+    __retres = 0;
+    goto return_label;
+  }
+  __retres = res;
+  return_label: return __retres;
+}
+
+int kgflags_double_array_get_count(kgflags_double_array_t const *arr)
+{
+  int __retres;
+  __retres = arr->_count;
+  return __retres;
+}
+
+double kgflags_double_array_get_item(kgflags_double_array_t const *arr,
+                                     int at)
+{
+  double __retres;
+  if (at < 0) goto _LOR;
+  else 
+    if (at >= arr->_count) {
+      _LOR: {
+              __retres = 0.0;
+              goto return_label;
+            }
+    }
+  char const *str = (char const *)*(arr->_items + at);
+  _Bool ok = (_Bool)0;
+  double res = _kgflags_parse_double(str,& ok);
+  if (! ok) {
+    __retres = 0.0;
+    goto return_label;
+  }
+  __retres = res;
+  return_label: return __retres;
+}
+
+int kgflags_get_non_flag_args_count(void)
+{
+  int __retres;
+  __retres = _kgflags_g.non_flag_count;
+  return __retres;
+}
+
+char const *kgflags_get_non_flag_arg(int at)
+{
+  char const *__retres;
+  if (at < 0) goto _LOR;
+  else 
+    if (at >= _kgflags_g.non_flag_count) {
+      _LOR: {
+              __retres = (char const *)0;
+              goto return_label;
+            }
+    }
+  __retres = _kgflags_g.non_flag_args[at];
+  return_label: return __retres;
+}
+
+static _Bool _kgflags_is_flag(char const *arg)
+{
+  _Bool __retres;
+  char const *tmp;
+  tmp = _kgflags_get_flag_name(arg);
+  __retres = (_Bool)(tmp != (char const *)0);
+  return __retres;
+}
+
+static char const *_kgflags_get_flag_name(char const *arg)
+{
+  char const *__retres;
+  size_t tmp_0;
+  int tmp_1;
+  unsigned long prefix_len = strlen(_kgflags_g.flag_prefix);
+  tmp_0 = strlen(arg);
+  ;
+  if (tmp_0 < prefix_len) {
+    __retres = (char const *)0;
+    goto return_label;
+  }
+  tmp_1 = strncmp(arg,_kgflags_g.flag_prefix,prefix_len);
+  if (tmp_1 != 0) {
+    __retres = (char const *)0;
+    goto return_label;
+  }
+  __retres = arg + prefix_len;
+  return_label: return __retres;
+}
+
+static void _kgflags_add_flag(_kgflags_flag_t flag)
+{
+  _kgflags_flag_t *tmp;
+  tmp = _kgflags_get_flag(flag.name,(_Bool *)0);
+  if (tmp != (_kgflags_flag_t *)0) {
+    _kgflags_add_error(KGFLAGS_ERROR_KIND_DUPLICATE_FLAG,flag.name,
+                       (char const *)0);
+    goto return_label;
+  }
+  if (_kgflags_g.flags_count >= 256) {
+    _kgflags_add_error(KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS,(char const *)0,
+                       (char const *)0);
+    goto return_label;
+  }
+  _kgflags_g.flags[_kgflags_g.flags_count] = flag;
+  (_kgflags_g.flags_count) ++;
+  return_label: return;
+}
+
+static _kgflags_flag_t *_kgflags_get_flag(char const *name,
+                                          _Bool *out_prefix_no)
+{
+  _kgflags_flag_t *__retres;
+  if (out_prefix_no) *out_prefix_no = (_Bool)0;
+  {
+    int i = 0;
+    while (i < _kgflags_g.flags_count) {
+      {
+        int tmp;
+        _kgflags_flag_t *flag = & _kgflags_g.flags[i];
+        tmp = strcmp(name,flag->name);
+        if (tmp == 0) {
+          __retres = flag;
+          goto return_label;
+        }
+        if (flag->kind == (unsigned int)KGFLAGS_FLAG_KIND_BOOL) {
+          char *tmp_1;
+          tmp_1 = strstr(name,"no-");
+          ;
+          if ((void *)tmp_1 == (void *)name) {
+            int tmp_0;
+            tmp_0 = strcmp(name + 3,flag->name);
+            if (tmp_0 == 0) {
+              if (out_prefix_no) *out_prefix_no = (_Bool)1;
+              __retres = flag;
+              goto return_label;
+            }
+          }
+        }
+      }
+      i ++;
+    }
+  }
+  __retres = (_kgflags_flag_t *)0;
+  return_label: return __retres;
+}
+
+static int _kgflags_parse_int(char const *str, _Bool *out_ok)
+{
+  int __retres;
+  *out_ok = (_Bool)0;
+  char *end = (char *)0;
+  long res_l = strtol(str,& end,10);
+  if ((void *)end == (void *)str) goto _LOR;
+  else 
+    if ((int)*end != '\000') goto _LOR;
+    else 
+      if (res_l > (long)2147483647) goto _LOR;
+      else 
+        if (res_l < (long)(-2147483647 - 1)) goto _LOR;
+        else 
+          if (res_l == -9223372036854775807L - 1L) goto _LOR_0;
+          else 
+            if (res_l == 9223372036854775807L) {
+              _LOR_0: ;
+              if (34 == __fc_errno) {
+                _LOR:
+                {
+                  *out_ok = (_Bool)0;
+                  __retres = 0;
+                  goto return_label;
+                }
+              }
+            }
+  *out_ok = (_Bool)1;
+  __retres = (int)res_l;
+  return_label: return __retres;
+}
+
+static double _kgflags_parse_double(char const *str, _Bool *out_ok)
+{
+  double __retres;
+  *out_ok = (_Bool)0;
+  char *end = (char *)0;
+  double res = strtod(str,& end);
+  if ((void *)end == (void *)str) goto _LOR;
+  else 
+    if ((int)*end != '\000') goto _LOR;
+    else 
+      if (res == - ((double)INFINITY)) goto _LOR_0;
+      else 
+        if (res == (double)INFINITY) {
+          _LOR_0: ;
+          if (34 == __fc_errno) {
+            _LOR: {
+                    *out_ok = (_Bool)0;
+                    __retres = 0.0;
+                    goto return_label;
+                  }
+          }
+        }
+  *out_ok = (_Bool)1;
+  __retres = res;
+  return_label: return __retres;
+}
+
+static void _kgflags_add_error(_kgflags_error_kind_t kind,
+                               char const *flag_name, char const *arg)
+{
+  _kgflags_error_t err;
+  err.kind = kind;
+  err.flag_name = flag_name;
+  err.arg = arg;
+  if (_kgflags_g.errors_count >= 512) goto return_label;
+  _kgflags_g.errors[_kgflags_g.errors_count] = err;
+  (_kgflags_g.errors_count) ++;
+  return_label: return;
+}
+
+static void _kgflags_assign_default_values(void)
+{
+  int i = 0;
+  while (i < _kgflags_g.flags_count) {
+    {
+      _kgflags_flag_t *flag = & _kgflags_g.flags[i];
+      if (flag->assigned) goto _LOR;
+      else 
+        if (flag->required) _LOR: goto __Cont;
+      switch (flag->kind) {
+        case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_STRING:
+        {
+          *(flag->result.string_value) = flag->default_value.string_value;
+          flag->assigned = (_Bool)1;
+          break;
+        }
+        case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_BOOL:
+        {
+          *(flag->result.bool_value) = flag->default_value.bool_value;
+          flag->assigned = (_Bool)1;
+          break;
+        }
+        case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_INT:
+        {
+          *(flag->result.int_value) = flag->default_value.int_value;
+          flag->assigned = (_Bool)1;
+          break;
+        }
+        case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_DOUBLE:
+        {
+          *(flag->result.double_value) = flag->default_value.double_value;
+          flag->assigned = (_Bool)1;
+          break;
+        }
+        default: break;
+      }
+    }
+    __Cont: i ++;
+  }
+  return;
+}
+
+static _Bool _kgflags_add_non_flag_arg(char const *arg)
+{
+  _Bool __retres;
+  if (_kgflags_g.non_flag_count >= 512) {
+    _kgflags_add_error(KGFLAGS_ERROR_KIND_TOO_MANY_NON_FLAG_ARGS,
+                       (char const *)0,(char const *)0);
+    __retres = (_Bool)0;
+    goto return_label;
+  }
+  _kgflags_g.non_flag_args[_kgflags_g.non_flag_count] = arg;
+  (_kgflags_g.non_flag_count) ++;
+  __retres = (_Bool)1;
+  return_label: return __retres;
+}
+
+static char const *_kgflags_consume_arg(void)
+{
+  char const *__retres;
+  if (_kgflags_g.arg_cursor >= _kgflags_g.argc) {
+    __retres = (char const *)0;
+    goto return_label;
+  }
+  char const *res = (char const *)*(_kgflags_g.argv + _kgflags_g.arg_cursor);
+  (_kgflags_g.arg_cursor) ++;
+  __retres = res;
+  return_label: return __retres;
+}
+
+static char const *_kgflags_peek_arg(void)
+{
+  char const *__retres;
+  if (_kgflags_g.arg_cursor >= _kgflags_g.argc) {
+    __retres = (char const *)0;
+    goto return_label;
+  }
+  __retres = (char const *)*(_kgflags_g.argv + _kgflags_g.arg_cursor);
+  return_label: return __retres;
+}
+
+static void _kgflags_parse_flag(_kgflags_flag_t *flag, _Bool prefix_no)
+{
+  switch (flag->kind) {
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_STRING:
+    {
+      char const *val = _kgflags_consume_arg();
+      if (! val) {
+        flag->error = (_Bool)1;
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_MISSING_VALUE,flag->name,
+                           (char const *)0);
+        goto return_label;
+      }
+      *(flag->result.string_value) = val;
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_BOOL:
+    {
+      *(flag->result.bool_value) = (_Bool)(! prefix_no);
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_INT:
+    {
+      char const *val_0 = _kgflags_consume_arg();
+      if (! val_0) {
+        flag->error = (_Bool)1;
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_MISSING_VALUE,flag->name,
+                           (char const *)0);
+        goto return_label;
+      }
+      _Bool ok = (_Bool)0;
+      int int_val = _kgflags_parse_int(val_0,& ok);
+      if (! ok) {
+        flag->error = (_Bool)1;
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_INT,flag->name,val_0);
+        goto return_label;
+      }
+      *(flag->result.int_value) = int_val;
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_DOUBLE:
+    {
+      char const *val_1 = _kgflags_consume_arg();
+      if (! val_1) {
+        flag->error = (_Bool)1;
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_MISSING_VALUE,flag->name,
+                           (char const *)0);
+        goto return_label;
+      }
+      _Bool ok_0 = (_Bool)0;
+      double double_val = _kgflags_parse_double(val_1,& ok_0);
+      if (! ok_0) {
+        flag->error = (_Bool)1;
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_DOUBLE,flag->name,
+                           val_1);
+        goto return_label;
+      }
+      *(flag->result.double_value) = double_val;
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_STRING_ARRAY:
+    {
+      int initial_cursor = _kgflags_g.arg_cursor;
+      int count = 0;
+      while (1) {
+        {
+          char const *val_2 = _kgflags_peek_arg();
+          if (val_2 == (char const *)0) goto _LOR;
+          else {
+            _Bool tmp_5;
+            tmp_5 = _kgflags_is_flag(val_2);
+            if (tmp_5) _LOR: break;
+          }
+          _kgflags_consume_arg();
+          count ++;
+        }
+      }
+      kgflags_string_array_t *arr = flag->result.string_array;
+      arr->_items = _kgflags_g.argv + initial_cursor;
+      arr->_count = count;
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_INT_ARRAY:
+    {
+      int initial_cursor_0 = _kgflags_g.arg_cursor;
+      int count_0 = 0;
+      _Bool all_args_ok = (_Bool)1;
+      while (1) {
+        {
+          char const *val_3 = _kgflags_peek_arg();
+          if (val_3 == (char const *)0) goto _LOR_0;
+          else {
+            _Bool tmp_7;
+            tmp_7 = _kgflags_is_flag(val_3);
+            if (tmp_7) _LOR_0: break;
+          }
+          _kgflags_consume_arg();
+          _Bool ok_1 = (_Bool)0;
+          _kgflags_parse_int(val_3,& ok_1);
+          if (! ok_1) {
+            flag->error = (_Bool)1;
+            _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_INT,flag->name,
+                               val_3);
+            all_args_ok = (_Bool)0;
+          }
+          count_0 ++;
+        }
+      }
+      kgflags_int_array_t *arr_0 = flag->result.int_array;
+      if (all_args_ok) {
+        arr_0->_items = _kgflags_g.argv + initial_cursor_0;
+        arr_0->_count = count_0;
+      }
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    case (_kgflags_flag_kind_t)KGFLAGS_FLAG_KIND_DOUBLE_ARRAY:
+    {
+      int initial_cursor_1 = _kgflags_g.arg_cursor;
+      int count_1 = 0;
+      _Bool all_args_ok_0 = (_Bool)1;
+      while (1) {
+        {
+          char const *val_4 = _kgflags_peek_arg();
+          if (val_4 == (char const *)0) goto _LOR_1;
+          else {
+            _Bool tmp_9;
+            tmp_9 = _kgflags_is_flag(val_4);
+            if (tmp_9) _LOR_1: break;
+          }
+          _kgflags_consume_arg();
+          _Bool ok_2 = (_Bool)0;
+          _kgflags_parse_double(val_4,& ok_2);
+          if (! ok_2) {
+            flag->error = (_Bool)1;
+            _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_DOUBLE,flag->name,
+                               val_4);
+            all_args_ok_0 = (_Bool)0;
+          }
+          count_1 ++;
+        }
+      }
+      kgflags_double_array_t *arr_1 = flag->result.double_array;
+      if (all_args_ok_0) {
+        arr_1->_items = _kgflags_g.argv + initial_cursor_1;
+        arr_1->_count = count_1;
+      }
+      flag->assigned = (_Bool)1;
+      break;
+    }
+    default: break;
+  }
+  return_label: return;
+}
+
+int main(int argc, char **argv)
+{
+  int __retres;
+  _Bool tmp;
+  char const *to_print = (char const *)0;
+  kgflags_string("to-print",(char const *)0,"String to print.",(_Bool)1,
+                 & to_print);
+  tmp = kgflags_parse(argc,argv);
+  if (! tmp) {
+    kgflags_print_errors();
+    kgflags_print_usage();
+    __retres = 1;
+    goto return_label;
+  }
+  puts(to_print);
+  __retres = 0;
+  return_label: return __retres;
+}
+
+
diff --git a/kgflags/.frama-c/kgflags-simple.parse/metrics.log b/kgflags/.frama-c/kgflags-simple.parse/metrics.log
new file mode 100644
index 000000000..7fee11bd6
--- /dev/null
+++ b/kgflags/.frama-c/kgflags-simple.parse/metrics.log
@@ -0,0 +1,55 @@
+[metrics] Defined functions (34)
+======================
+ _kgflags_add_error (14 calls); _kgflags_add_flag (7 calls);
+ _kgflags_add_non_flag_arg (1 call); _kgflags_assign_default_values (1 call);
+ _kgflags_consume_arg (7 calls); _kgflags_get_flag (2 calls);
+ _kgflags_get_flag_name (2 calls); _kgflags_is_flag (4 calls);
+ _kgflags_parse_double (3 calls); _kgflags_parse_flag (1 call);
+ _kgflags_parse_int (3 calls); _kgflags_peek_arg (3 calls);
+ eva_main (0 call); kgflags_bool (0 call); kgflags_double (0 call);
+ kgflags_double_array (0 call); kgflags_double_array_get_count (0 call);
+ kgflags_double_array_get_item (0 call); kgflags_get_non_flag_arg (0 call);
+ kgflags_get_non_flag_args_count (0 call); kgflags_int (0 call);
+ kgflags_int_array (0 call); kgflags_int_array_get_count (0 call);
+ kgflags_int_array_get_item (0 call); kgflags_parse (1 call);
+ kgflags_print_errors (1 call); kgflags_print_usage (1 call);
+ kgflags_set_custom_description (0 call); kgflags_set_prefix (0 call);
+ kgflags_string (1 call); kgflags_string_array (0 call);
+ kgflags_string_array_get_count (0 call);
+ kgflags_string_array_get_item (0 call); main (1 call); 
+
+Specified-only functions (0)
+============================
+ 
+
+Undefined and unspecified functions (0)
+=======================================
+ 
+
+'Extern' global variables (0)
+=============================
+ 
+
+Potential entry points (17)
+===========================
+ eva_main; kgflags_bool; kgflags_double; kgflags_double_array;
+  kgflags_double_array_get_count; kgflags_double_array_get_item;
+  kgflags_get_non_flag_arg; kgflags_get_non_flag_args_count; kgflags_int;
+  kgflags_int_array; kgflags_int_array_get_count; kgflags_int_array_get_item;
+  kgflags_set_custom_description; kgflags_set_prefix; kgflags_string_array;
+  kgflags_string_array_get_count; kgflags_string_array_get_item; 
+
+Global metrics
+============== 
+Sloc = 659
+Decision point = 113
+Global variables = 1
+If = 85
+Loop = 10
+Goto = 44
+Assignment = 245
+Exit point = 34
+Function = 34
+Function call = 98
+Pointer dereferencing = 140
+Cyclomatic complexity = 147
diff --git a/kgflags/.frama-c/kgflags-simple.parse/warnings.log b/kgflags/.frama-c/kgflags-simple.parse/warnings.log
new file mode 100644
index 000000000..e69de29bb
diff --git a/kgflags/.frama-c/path.mk b/kgflags/.frama-c/path.mk
new file mode 100644
index 000000000..6f0bae734
--- /dev/null
+++ b/kgflags/.frama-c/path.mk
@@ -0,0 +1,7 @@
+FRAMAC_BIN=/home/andr/git/frama-c-quebec/bin
+ifeq ($(wildcard $(FRAMAC_BIN)),)
+# Frama-C not installed locally; using the version in the PATH
+else
+FRAMAC=$(FRAMAC_BIN)/frama-c
+FRAMAC_GUI=$(FRAMAC_BIN)/frama-c-gui
+endif
diff --git a/kgflags/LICENSE b/kgflags/LICENSE
new file mode 100644
index 000000000..88adfd9f4
--- /dev/null
+++ b/kgflags/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Krzysztof Gabis
+
+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.
diff --git a/kgflags/examples/full_api.c b/kgflags/examples/full_api.c
new file mode 100644
index 000000000..38586e6f5
--- /dev/null
+++ b/kgflags/examples/full_api.c
@@ -0,0 +1,60 @@
+#define KGFLAGS_IMPLEMENTATION
+#include "../kgflags.h"
+
+int main(int argc, char **argv) {
+    const char *string_val = NULL;
+    kgflags_string("string", "lorem", "String flag.", true, &string_val);
+
+    bool bool_val = false;
+    kgflags_bool("bool", false, "Boolean flag.", true, &bool_val);
+
+    int int_val = 0;
+    kgflags_int("int", 0, "Integer flag.", true, &int_val);
+
+    double double_val = 0;
+    kgflags_double("double", 0.0, "Double flag.", true, &double_val);
+
+    kgflags_string_array_t string_arr;
+    kgflags_string_array("string-array", "String array flag.", true, &string_arr);
+
+    kgflags_int_array_t int_arr;
+    kgflags_int_array("int-array", "Int array flag.", true, &int_arr);
+
+    kgflags_double_array_t double_arr;
+    kgflags_double_array("double-array", "Double array flag.", true, &double_arr);
+
+    kgflags_set_custom_description("Usage of fullapi [-FLAGS]:");
+    kgflags_set_prefix("-");
+    if (!kgflags_parse(argc, argv)) {
+        kgflags_print_errors();
+        kgflags_print_usage();
+        return 1;
+    }
+
+    printf("string_val: %s\n", string_val);
+    printf("bool_val: %s\n", bool_val ? "true" : "false");
+    printf("int_val: %d\n", int_val);
+    printf("double_val: %f\n", double_val);
+
+    printf("string-arr count: %d\n", kgflags_string_array_get_count(&string_arr));
+    for (int i = 0; i < kgflags_string_array_get_count(&string_arr); i++) {
+        printf("string-arr [%d]\n: %s", i, kgflags_string_array_get_item(&string_arr, i));
+    }
+
+    printf("int-arr count: %d\n", kgflags_int_array_get_count(&int_arr));
+    for (int i = 0; i < kgflags_int_array_get_count(&int_arr); i++) {
+        printf("int-arr [%d]: %d\n", i, kgflags_int_array_get_item(&int_arr, i));
+    }
+
+    printf("double-arr count: %d\n", kgflags_double_array_get_count(&double_arr));
+    for (int i = 0; i < kgflags_double_array_get_count(&double_arr); i++) {
+        printf("double-arr [%d]: %1.4g\n", i, kgflags_double_array_get_item(&double_arr, i));
+    }
+
+    int non_flag_count = kgflags_get_non_flag_args_count();
+    for (int i = 0; i < non_flag_count; i++) {
+        printf("Non-flag arguments [%d] = %s\n", i, kgflags_get_non_flag_arg(i));
+    }
+
+    return 0;
+}
diff --git a/kgflags/examples/simple.c b/kgflags/examples/simple.c
new file mode 100644
index 000000000..b7ccd7ca6
--- /dev/null
+++ b/kgflags/examples/simple.c
@@ -0,0 +1,14 @@
+#define KGFLAGS_IMPLEMENTATION
+#include "../kgflags.h"
+
+int main(int argc, char **argv) {
+    const char *to_print = NULL;  // guaranteed to be assigned only if kgflags_parse succeeds
+    kgflags_string("to-print", NULL, "String to print.", true, &to_print);
+    if (!kgflags_parse(argc, argv)) {
+        kgflags_print_errors();
+        kgflags_print_usage();
+        return 1;
+    }
+    puts(to_print);
+    return 0;
+}
diff --git a/kgflags/kgflags.h b/kgflags/kgflags.h
new file mode 100644
index 000000000..da24186ae
--- /dev/null
+++ b/kgflags/kgflags.h
@@ -0,0 +1,851 @@
+/*
+ kgflags v0.6.1
+ http://github.com/kgabis/kgflags/
+ Copyright (c) 2020 Krzysztof Gabis
+ 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.
+
+### About:
+
+ kgflags is a simple to use command-line flag parsing library.
+
+ Visit https://github.com/kgabis/kgflags/tree/master/readme.md for more info.
+
+### Example:
+
+#define KGFLAGS_IMPLEMENTATION
+#include "kgflags.h"
+
+int main(int argc, char **argv) {
+    const char *to_print = NULL;  // guaranteed to be assigned only if kgflags_parse succeeds
+    kgflags_string("to-print", NULL, "String to print.", true, &to_print);
+    if (!kgflags_parse(argc, argv)) {
+        kgflags_print_errors();
+        kgflags_print_usage();
+        return 1;
+    }
+    puts(to_print);
+    return 0;
+}
+*/
+
+#ifndef KGFLAGS_INCLUDE_KGFLAGS_H
+#define KGFLAGS_INCLUDE_KGFLAGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
+typedef struct kgflags_string_array {
+    char **_items; // private
+    int _count; // private
+} kgflags_string_array_t;
+
+typedef struct kgflags_int_array {
+    char **_items; // private
+    int _count; // private
+} kgflags_int_array_t;
+
+typedef struct kgflags_double_array {
+    char **_items; // private
+    int _count; // private
+} kgflags_double_array_t;
+
+#ifndef KGFLAGS_MAX_FLAGS
+#define KGFLAGS_MAX_FLAGS 256
+#endif
+
+#ifndef KGFLAGS_MAX_NON_FLAG_ARGS
+#define KGFLAGS_MAX_NON_FLAG_ARGS 512
+#endif
+
+#ifndef KGFLAGS_MAX_ERRORS
+#define KGFLAGS_MAX_ERRORS 512
+#endif
+
+// Functions used to declare flags. If kgflags_parse succeeds values are assigned to out_res/out_arr. Description is optional.
+void kgflags_string(const char *name, const char *default_value, const char *description, bool required, const char** out_res);
+void kgflags_bool(const char *name, bool default_value, const char *description, bool required, bool *out_res);
+void kgflags_int(const char *name, int default_value, const char *description, bool required, int *out_res);
+void kgflags_double(const char *name, double default_value, const char *description, bool required, double *out_res);
+
+// Arrays are parsed until first flag argument. e.g. "--arr 1 2 3 --next-flag" -> arr == [1, 2, 3].
+void kgflags_string_array(const char *name, const char *description, bool required, kgflags_string_array_t *out_arr);
+void kgflags_int_array(const char *name, const char *description, bool required, kgflags_int_array_t *out_arr);
+void kgflags_double_array(const char *name, const char *description, bool required, kgflags_double_array_t *out_arr);
+
+// Optionally sets prefix used for flags (such as "--", "-" or "/").
+// Default prefix is "--". Should be called *before* calling kgflags_parse.
+void kgflags_set_prefix(const char *prefix);
+
+// Parses arguments and assign values to declared flags.
+bool kgflags_parse(int argc, char **argv);
+
+// Prints errors that might've occured when declaring flags or during flag parsing.
+void kgflags_print_errors(void);
+
+// Prints usage based on flags declared with kgflags_string, kgflags_int etc.
+// Can be customized with custom description by calling kgflags_set_custom_description.
+// By default it starts with "Usage of ./app:". If custom_description is set with
+// kgflags_set_custom_description it will print it instead.
+void kgflags_print_usage(void);
+
+// Sets custom description printed by kgflags_print_usage.
+// e.g. kgflags_set_custom_description("Usage: ./app [--FLAGS] [file ...]");
+void kgflags_set_custom_description(const char *description);
+
+int kgflags_string_array_get_count(const kgflags_string_array_t *arr);
+const char* kgflags_string_array_get_item(const kgflags_string_array_t *arr, int at);
+
+// Result is parsed from string every time you get an item.
+int kgflags_int_array_get_count(const kgflags_int_array_t *arr);
+int kgflags_int_array_get_item(const kgflags_int_array_t *arr, int at);
+
+// Result is parsed from string every time you get an item.
+int kgflags_double_array_get_count(const kgflags_double_array_t *arr);
+double kgflags_double_array_get_item(const kgflags_double_array_t *arr, int at);
+
+// Returns arguments that don't belong to any flags.
+// e.g. if we defined a flag named "file" and call "./app arg0 --file test arg1"
+// then non-flag arguments' count is 2 and non-flag[0] is arg0 and non-flag[1] is arg1.
+int kgflags_get_non_flag_args_count(void);
+const char* kgflags_get_non_flag_arg(int at);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* KGFLAGS_INCLUDE_KGFLAGS_H */
+
+#ifdef KGFLAGS_IMPLEMENTATION
+#undef KGFLAGS_IMPLEMENTATION
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <math.h>
+
+typedef enum _kgflags_flag_kind {
+    KGFLAGS_FLAG_KIND_NONE,
+    KGFLAGS_FLAG_KIND_STRING,
+    KGFLAGS_FLAG_KIND_BOOL,
+    KGFLAGS_FLAG_KIND_INT,
+    KGFLAGS_FLAG_KIND_DOUBLE,
+    KGFLAGS_FLAG_KIND_STRING_ARRAY,
+    KGFLAGS_FLAG_KIND_INT_ARRAY,
+    KGFLAGS_FLAG_KIND_DOUBLE_ARRAY,
+} _kgflags_flag_kind_t;
+
+typedef struct _kgflags_flag {
+    const char *name;
+    const char *description;
+    union {
+        const char *string_value;
+        bool bool_value;
+        int int_value;
+        double double_value;
+    } default_value;
+    union {
+        const char **string_value;
+        bool *bool_value;
+        int *int_value;
+        double *double_value;
+        kgflags_string_array_t *string_array;
+        kgflags_int_array_t *int_array;
+        kgflags_double_array_t *double_array;
+    } result;
+    bool assigned;
+    bool error;
+    bool required;
+    _kgflags_flag_kind_t kind;
+} _kgflags_flag_t;
+
+typedef enum _kgflags_error_kind {
+    KGFLAGS_ERROR_KIND_NONE,
+    KGFLAGS_ERROR_KIND_MISSING_VALUE,
+    KGFLAGS_ERROR_KIND_UNKNOWN_FLAG,
+    KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG,
+    KGFLAGS_ERROR_KIND_INVALID_INT,
+    KGFLAGS_ERROR_KIND_INVALID_DOUBLE,
+    KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS,
+    KGFLAGS_ERROR_KIND_TOO_MANY_NON_FLAG_ARGS,
+    KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT,
+    KGFLAGS_ERROR_KIND_DUPLICATE_FLAG,
+    KGFLAGS_ERROR_KIND_PREFIX_NO,
+} _kgflags_error_kind_t;
+
+typedef struct _kgflags_error {
+    const char *flag_name;
+    const char *arg;
+    _kgflags_error_kind_t kind;
+} _kgflags_error_t;
+
+static bool _kgflags_is_flag(const char* arg);
+static const char* _kgflags_get_flag_name(const char* arg);
+static void _kgflags_add_flag(_kgflags_flag_t arg);
+static _kgflags_flag_t* _kgflags_get_flag(const char* name, bool *out_prefix_no);
+static int _kgflags_parse_int(const char *str, bool *out_ok);
+static double _kgflags_parse_double(const char *str, bool *out_ok);
+static void _kgflags_add_error(_kgflags_error_kind_t kind, const char *flag, const char *arg);
+static void _kgflags_assign_default_values(void);
+static bool _kgflags_add_non_flag_arg(const char* arg);
+static const char* _kgflags_consume_arg(void);
+static const char* _kgflags_peek_arg(void);
+static void _kgflags_parse_flag(_kgflags_flag_t *flag, bool prefix_no);
+
+static struct {
+    int flags_count;
+    _kgflags_flag_t flags[KGFLAGS_MAX_FLAGS];
+
+    int non_flag_count;
+    const char* non_flag_args[KGFLAGS_MAX_NON_FLAG_ARGS];
+
+    int errors_count;
+    _kgflags_error_t errors[KGFLAGS_MAX_ERRORS];
+
+    const char *flag_prefix;
+
+    int arg_cursor;
+    int argc;
+    char **argv;
+
+    const char *custom_description;
+} _kgflags_g;
+
+void kgflags_string(const char *name, const char *default_value, const char *description, bool required, const char** out_res) {
+    *out_res = NULL;
+
+    _kgflags_flag_t flag;
+    memset(&flag, 0, sizeof(_kgflags_flag_t));
+    flag.kind = KGFLAGS_FLAG_KIND_STRING;
+    flag.name = name;
+    flag.default_value.string_value = default_value;
+    flag.description = description;
+    flag.required = required;
+    flag.result.string_value = out_res;
+    flag.assigned = false;
+    _kgflags_add_flag(flag);
+}
+
+void kgflags_bool(const char *name, bool default_value, const char *description, bool required, bool *out_res) {
+    *out_res = false;
+
+    if (strstr(name, "no-") == name) {
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_PREFIX_NO, name, NULL);
+        return;
+    }
+
+    _kgflags_flag_t flag;
+    memset(&flag, 0, sizeof(_kgflags_flag_t));
+    flag.kind = KGFLAGS_FLAG_KIND_BOOL;
+    flag.name = name;
+    flag.default_value.bool_value = default_value;
+    flag.description = description;
+    flag.required = required;
+    flag.result.bool_value = out_res;
+    flag.assigned = false;
+    _kgflags_add_flag(flag);
+}
+
+void kgflags_int(const char *name, int default_value, const char *description, bool required, int *out_res) {
+    *out_res = 0;
+
+    _kgflags_flag_t flag;
+    memset(&flag, 0, sizeof(_kgflags_flag_t));
+    flag.kind = KGFLAGS_FLAG_KIND_INT;
+    flag.name = name;
+    flag.default_value.int_value = default_value;
+    flag.description = description;
+    flag.required = required;
+    flag.result.int_value = out_res;
+    flag.assigned = false;
+    _kgflags_add_flag(flag);
+}
+
+void kgflags_double(const char *name, double default_value, const char *description, bool required, double *out_res) {
+    *out_res = 0.0;
+
+    _kgflags_flag_t flag;
+    memset(&flag, 0, sizeof(_kgflags_flag_t));
+    flag.kind = KGFLAGS_FLAG_KIND_DOUBLE;
+    flag.name = name;
+    flag.default_value.double_value = default_value;
+    flag.description = description;
+    flag.required = required;
+    flag.result.double_value = out_res;
+    flag.assigned = false;
+    _kgflags_add_flag(flag);
+}
+
+void kgflags_string_array(const char *name, const char *description, bool required, kgflags_string_array_t *out_arr) {
+    out_arr->_items = NULL;
+    out_arr->_count = 0;
+
+    _kgflags_flag_t flag;
+    memset(&flag, 0, sizeof(_kgflags_flag_t));
+    flag.kind = KGFLAGS_FLAG_KIND_STRING_ARRAY;
+    flag.name = name;
+    flag.description = description;
+    flag.required = required;
+    flag.result.string_array = out_arr;
+    flag.assigned = false;
+    _kgflags_add_flag(flag);
+}
+
+void kgflags_int_array(const char *name, const char *description, bool required, kgflags_int_array_t *out_arr) {
+    out_arr->_items = NULL;
+    out_arr->_count = 0;
+
+    _kgflags_flag_t flag;
+    memset(&flag, 0, sizeof(_kgflags_flag_t));
+    flag.kind = KGFLAGS_FLAG_KIND_INT_ARRAY;
+    flag.name = name;
+    flag.description = description;
+    flag.required = required;
+    flag.result.int_array = out_arr;
+    flag.assigned = false;
+    _kgflags_add_flag(flag);
+}
+
+void kgflags_double_array(const char *name, const char *description, bool required, kgflags_double_array_t *out_arr) {
+    out_arr->_items = NULL;
+    out_arr->_count = 0;
+
+    _kgflags_flag_t flag;
+    memset(&flag, 0, sizeof(_kgflags_flag_t));
+    flag.kind = KGFLAGS_FLAG_KIND_DOUBLE_ARRAY;
+    flag.name = name;
+    flag.description = description;
+    flag.required = required;
+    flag.result.double_array = out_arr;
+    flag.assigned = false;
+    _kgflags_add_flag(flag);
+}
+
+void kgflags_set_prefix(const char *prefix) {
+    _kgflags_g.flag_prefix = prefix;
+}
+
+bool kgflags_parse(int argc, char **argv) {
+    _kgflags_g.argc = argc;
+    _kgflags_g.argv = argv;
+    _kgflags_g.arg_cursor = 1;
+
+    if (_kgflags_g.flag_prefix == NULL) {
+        _kgflags_g.flag_prefix = "--";
+    }
+
+    if (_kgflags_g.errors_count > 0) {
+        return false;
+    }
+
+    const char *arg = NULL;
+    while ((arg = _kgflags_consume_arg()) != NULL) {
+        _kgflags_flag_t *flag = NULL;
+        bool is_flag = _kgflags_is_flag(arg);
+        bool prefix_no = false;
+        if (is_flag) {
+            const char *flag_name = _kgflags_get_flag_name(arg);
+            flag = _kgflags_get_flag(flag_name, &prefix_no);
+            if (flag == NULL) {
+                _kgflags_add_error(KGFLAGS_ERROR_KIND_UNKNOWN_FLAG, flag_name, NULL);
+                continue;
+            }
+        } else {
+            _kgflags_add_non_flag_arg(arg);
+            continue;
+        }
+
+        if (flag->assigned) {
+            _kgflags_add_error(KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT, flag->name, NULL);
+        }
+
+        _kgflags_parse_flag(flag, prefix_no);
+    }
+
+    _kgflags_assign_default_values();
+
+    for (int i = 0; i < _kgflags_g.flags_count; i++) {
+        _kgflags_flag_t *flag = &_kgflags_g.flags[i];
+        if (flag->required && !flag->assigned && !flag->error) {
+            _kgflags_add_error(KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG, flag->name, NULL);
+        }
+    }
+
+    if (_kgflags_g.errors_count > 0) {
+        return false;
+    }
+
+    return true;
+}
+
+void kgflags_print_errors(void) {
+    for (int i = 0; i < _kgflags_g.errors_count; i++) {
+        _kgflags_error_t *err = &_kgflags_g.errors[i];
+        switch (err->kind) {
+            case KGFLAGS_ERROR_KIND_MISSING_VALUE: {
+                fprintf(stderr, "Missing value for flag: %s%s\n", _kgflags_g.flag_prefix,  err->flag_name);
+                break;
+            }
+            case KGFLAGS_ERROR_KIND_UNKNOWN_FLAG: {
+                fprintf(stderr, "Unrecognized flag: %s%s\n", _kgflags_g.flag_prefix, err->flag_name);
+                break;
+            }
+            case KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG: {
+                fprintf(stderr, "Unassigned required flag: %s%s\n", _kgflags_g.flag_prefix, err->flag_name);
+                break;
+            }
+            case KGFLAGS_ERROR_KIND_INVALID_INT: {
+                fprintf(stderr, "Invalid value for flag: %s%s (got %s, expected integer)\n", _kgflags_g.flag_prefix, err->flag_name, err->arg);
+                break;
+            }
+            case KGFLAGS_ERROR_KIND_INVALID_DOUBLE: {
+                fprintf(stderr, "Invalid value for flag: %s%s (got %s, expected number)\n", _kgflags_g.flag_prefix, err->flag_name, err->arg);
+                break;
+            }
+            case KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS: {
+                fprintf(stderr, "Too many flags declared.");
+                break;
+            }
+            case KGFLAGS_ERROR_KIND_TOO_MANY_NON_FLAG_ARGS: {
+                fprintf(stderr, "Too many non-flag arguments passed to program.");
+                break;
+            }
+            case KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT: {
+                fprintf(stderr, "Multiple assignment of flag: %s%s\n", _kgflags_g.flag_prefix, err->flag_name);
+                break;
+            }
+            case KGFLAGS_ERROR_KIND_DUPLICATE_FLAG: {
+                fprintf(stderr, "Redeclaration of flag: %s%s\n", _kgflags_g.flag_prefix, err->flag_name);
+                break;
+            }
+            case KGFLAGS_ERROR_KIND_PREFIX_NO: {
+                fprintf(stderr, "Used \"no-\" prefix when declaring boolean flag: %s%s\n", _kgflags_g.flag_prefix, err->flag_name);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+}
+
+void kgflags_print_usage() {
+    if (_kgflags_g.custom_description == NULL) {
+        fprintf(stderr, "Usage of %s:\n", _kgflags_g.argv[0]);
+    } else {
+        fprintf(stderr, "%s\n", _kgflags_g.custom_description);
+    }
+
+    fprintf(stderr, "Flags:\n");
+    for (int i = 0; i < _kgflags_g.flags_count; i++) {
+        _kgflags_flag_t *flag = &_kgflags_g.flags[i];
+        switch (flag->kind) {
+            case KGFLAGS_FLAG_KIND_STRING:
+                fprintf(stderr, "\t%s%s\t(string%s\n", _kgflags_g.flag_prefix, flag->name, flag->required ? ")" : ", optional)");
+                if (!flag->required) {
+                    fprintf(stderr, "\t\tDefault: %s\n", flag->default_value.string_value);
+                }
+                break;
+            case KGFLAGS_FLAG_KIND_BOOL: {
+                fprintf(stderr, "\t%s%s, %sno-%s\t(boolean%s\n", _kgflags_g.flag_prefix, flag->name, _kgflags_g.flag_prefix, flag->name,
+                    flag->required ? ")" : ", optional)");
+                if (!flag->required) {
+                    fprintf(stderr, "\t\tDefault: %s\n", flag->default_value.bool_value ? "True" : "False");
+                }
+                break;
+            }
+            case KGFLAGS_FLAG_KIND_INT: {
+                fprintf(stderr, "\t%s%s\t(integer%s\n", _kgflags_g.flag_prefix, flag->name, flag->required ? ")" : ", optional)");
+                if (!flag->required) {
+                    fprintf(stderr, "\t\tDefault: %d\n", flag->default_value.int_value);
+                }
+                break;
+            }
+            case KGFLAGS_FLAG_KIND_DOUBLE: {
+                fprintf(stderr, "\t%s%s\t(float%s\n", _kgflags_g.flag_prefix, flag->name, flag->required ? ")" : ", optional)");
+                if (!flag->required) {
+                    fprintf(stderr, "\t\tDefault: %1.4g\n", flag->default_value.double_value);
+                }
+                break;
+            }
+            case KGFLAGS_FLAG_KIND_STRING_ARRAY: {
+                fprintf(stderr, "\t%s%s\t(array of strings%s\n", _kgflags_g.flag_prefix, flag->name, flag->required ? ")" : ", optional)");
+                break;
+            }
+            case KGFLAGS_FLAG_KIND_INT_ARRAY: {
+                fprintf(stderr, "\t%s%s\t(array of integers%s\n", _kgflags_g.flag_prefix, flag->name, flag->required ? ")" : ", optional)");
+                break;
+            }
+            case KGFLAGS_FLAG_KIND_DOUBLE_ARRAY: {
+                fprintf(stderr, "\t%s%s\t(array of floats%s\n", _kgflags_g.flag_prefix, flag->name, flag->required ? ")" : ", optional)");
+                break;
+            }
+            default:
+                break;
+        }
+        if (flag->description) {
+            fprintf(stderr, "\t\t%s\n", flag->description);
+        }
+        fprintf(stderr, "\n");
+    }
+}
+
+void kgflags_set_custom_description(const char *description) {
+    _kgflags_g.custom_description = description;
+}
+
+int kgflags_string_array_get_count(const kgflags_string_array_t *arr) {
+    return arr->_count;
+}
+
+const char* kgflags_string_array_get_item(const kgflags_string_array_t *arr, int at) {
+    if (at < 0 || at >= arr->_count) {
+        return NULL;
+    }
+    return arr->_items[at];
+}
+
+int kgflags_int_array_get_count(const kgflags_int_array_t *arr) {
+    return arr->_count;
+}
+
+int kgflags_int_array_get_item(const kgflags_int_array_t *arr, int at) {
+    if (at < 0 || at >= arr->_count) {
+        return 0;
+    }
+    const char *str = arr->_items[at];
+    bool ok = false;
+    int res = _kgflags_parse_int(str, &ok);
+    if (!ok) {
+        return 0;
+    }
+    return res;
+}
+
+int kgflags_double_array_get_count(const kgflags_double_array_t *arr) {
+    return arr->_count;
+}
+
+double kgflags_double_array_get_item(const kgflags_double_array_t *arr, int at) {
+    if (at < 0 || at >= arr->_count) {
+        return 0.0;
+    }
+    const char *str = arr->_items[at];
+    bool ok = false;
+    double res = _kgflags_parse_double(str, &ok);
+    if (!ok) {
+        return 0.0;
+    }
+    return res;
+}
+
+int kgflags_get_non_flag_args_count(void) {
+    return _kgflags_g.non_flag_count;
+}
+
+const char* kgflags_get_non_flag_arg(int at) {
+    if (at < 0 || at >= _kgflags_g.non_flag_count) {
+        return NULL;
+    }
+    return _kgflags_g.non_flag_args[at];
+}
+
+/**************************************************************/
+/* INTERNAL FUNCTIONS */
+/**************************************************************/
+
+static bool _kgflags_is_flag(const char *arg) {
+    return _kgflags_get_flag_name(arg) != NULL;
+}
+
+static const char* _kgflags_get_flag_name(const char* arg) {
+    unsigned long prefix_len = strlen(_kgflags_g.flag_prefix);
+    if (strlen(arg) < prefix_len) {
+        return NULL;
+    }
+    if (strncmp(arg, _kgflags_g.flag_prefix, prefix_len) != 0) {
+        return NULL;
+    }
+    return arg + prefix_len;
+}
+
+static void _kgflags_add_flag(_kgflags_flag_t flag) {
+    if (_kgflags_get_flag(flag.name, NULL) != NULL) {
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_DUPLICATE_FLAG, flag.name, NULL);
+        return;
+    }
+    if (_kgflags_g.flags_count >= KGFLAGS_MAX_FLAGS) {
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS, NULL, NULL);
+        return;
+    }
+    _kgflags_g.flags[_kgflags_g.flags_count] = flag;
+    _kgflags_g.flags_count++;
+}
+
+static _kgflags_flag_t* _kgflags_get_flag(const char* name, bool *out_prefix_no) {
+    if (out_prefix_no) {
+        *out_prefix_no = false;
+    }
+    for (int i = 0; i < _kgflags_g.flags_count; i++) {
+        _kgflags_flag_t *flag = &_kgflags_g.flags[i];
+        if (strcmp(name, flag->name) == 0) {
+            return flag;
+        }
+        if (flag->kind == KGFLAGS_FLAG_KIND_BOOL && strstr(name, "no-") == name) {
+            if (strcmp(name + 3, flag->name) == 0) {
+                if (out_prefix_no) {
+                    *out_prefix_no = true;
+                }
+                return flag;
+            }
+        }
+    }
+    return NULL;
+}
+
+static int _kgflags_parse_int(const char *str, bool *out_ok) {
+    *out_ok = false;
+    char *end = NULL;
+    long res_l = strtol(str, &end, 10);
+    if (end == str || *end != '\0' || res_l > INT_MAX || res_l < INT_MIN
+    || ((res_l == LONG_MIN || res_l == LONG_MAX) && ERANGE == errno)) {
+        *out_ok = false;
+        return 0;
+    }
+    *out_ok = true;
+    return (int)res_l;
+}
+
+static double _kgflags_parse_double(const char *str, bool *out_ok) {
+    *out_ok = false;
+    char *end = NULL;
+    double res = strtod(str, &end);
+    if (end == str || *end != '\0'
+    || ((res == -HUGE_VAL || res == +HUGE_VAL) && ERANGE == errno)) {
+        *out_ok = false;
+        return 0.0;
+    }
+    *out_ok = true;
+    return res;
+}
+
+static void _kgflags_add_error(_kgflags_error_kind_t kind, const char *flag_name, const char *arg) {
+    _kgflags_error_t err;
+    err.kind = kind;
+    err.flag_name = flag_name;
+    err.arg = arg;
+    if (_kgflags_g.errors_count >= KGFLAGS_MAX_ERRORS) {
+        return;
+    }
+    _kgflags_g.errors[_kgflags_g.errors_count] = err;
+    _kgflags_g.errors_count++;
+}
+
+
+static void _kgflags_assign_default_values() {
+    for (int i = 0; i < _kgflags_g.flags_count; i++) {
+        _kgflags_flag_t *flag = &_kgflags_g.flags[i];
+        if (flag->assigned || flag->required) {
+            continue;
+        }
+        switch (flag->kind) {
+            case KGFLAGS_FLAG_KIND_STRING: {
+                *flag->result.string_value = flag->default_value.string_value;
+                flag->assigned = true;
+                break;
+            }
+            case KGFLAGS_FLAG_KIND_BOOL: {
+                *flag->result.bool_value = flag->default_value.bool_value;
+                flag->assigned = true;
+                break;
+            }
+            case KGFLAGS_FLAG_KIND_INT: {
+                *flag->result.int_value = flag->default_value.int_value;
+                flag->assigned = true;
+                break;
+            }
+            case KGFLAGS_FLAG_KIND_DOUBLE: {
+                *flag->result.double_value = flag->default_value.double_value;
+                flag->assigned = true;
+                break;
+            }
+            default:
+                break;
+        }
+    }
+}
+
+static bool _kgflags_add_non_flag_arg(const char* arg) {
+    if (_kgflags_g.non_flag_count >= KGFLAGS_MAX_NON_FLAG_ARGS) {
+        _kgflags_add_error(KGFLAGS_ERROR_KIND_TOO_MANY_NON_FLAG_ARGS, NULL, NULL);
+        return false;
+    }
+    _kgflags_g.non_flag_args[_kgflags_g.non_flag_count] = arg;
+    _kgflags_g.non_flag_count++;
+    return true;
+}
+
+static const char* _kgflags_consume_arg() {
+    if (_kgflags_g.arg_cursor >= _kgflags_g.argc) {
+        return NULL;
+    }
+    const char *res = _kgflags_g.argv[_kgflags_g.arg_cursor];
+    _kgflags_g.arg_cursor++;
+    return res;
+}
+
+static const char* _kgflags_peek_arg() {
+    if (_kgflags_g.arg_cursor >= _kgflags_g.argc) {
+        return NULL;
+    }
+    return _kgflags_g.argv[_kgflags_g.arg_cursor];
+}
+
+static void _kgflags_parse_flag(_kgflags_flag_t *flag, bool prefix_no) {
+    switch (flag->kind) {
+        case KGFLAGS_FLAG_KIND_STRING: {
+            const char *val = _kgflags_consume_arg();
+            if (!val) {
+                flag->error = true;
+                _kgflags_add_error(KGFLAGS_ERROR_KIND_MISSING_VALUE, flag->name, NULL);
+                return;
+            }
+            *flag->result.string_value = val;
+            flag->assigned = true;
+            break;
+        }
+        case KGFLAGS_FLAG_KIND_BOOL: {
+            *flag->result.bool_value = !prefix_no;
+            flag->assigned = true;
+            break;
+        }
+        case KGFLAGS_FLAG_KIND_INT: {
+            const char *val = _kgflags_consume_arg();
+            if (!val) {
+                flag->error = true;
+                _kgflags_add_error(KGFLAGS_ERROR_KIND_MISSING_VALUE, flag->name, NULL);
+                return;
+            }
+            bool ok = false;
+            int int_val = _kgflags_parse_int(val, &ok);
+            if (!ok) {
+                flag->error = true;
+                _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_INT, flag->name, val);
+                return;
+            }
+            *flag->result.int_value = int_val;
+            flag->assigned = true;
+            break;
+        }
+        case KGFLAGS_FLAG_KIND_DOUBLE: {
+            const char *val = _kgflags_consume_arg();
+            if (!val) {
+                flag->error = true;
+                _kgflags_add_error(KGFLAGS_ERROR_KIND_MISSING_VALUE, flag->name, NULL);
+                return;
+            }
+            bool ok = false;
+            double double_val = _kgflags_parse_double(val, &ok);
+            if (!ok) {
+                flag->error = true;
+                _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_DOUBLE, flag->name, val);
+                return;
+            }
+            *flag->result.double_value = double_val;
+            flag->assigned = true;
+            break;
+        }
+        case KGFLAGS_FLAG_KIND_STRING_ARRAY: {
+            int initial_cursor = _kgflags_g.arg_cursor;
+            int count = 0;
+            while (true) {
+                const char *val = _kgflags_peek_arg();
+                if (val == NULL || _kgflags_is_flag(val)) {
+                    break;
+                }
+                _kgflags_consume_arg();
+                count++;
+            }
+            kgflags_string_array_t *arr = flag->result.string_array;
+            arr->_items = _kgflags_g.argv + initial_cursor;
+            arr->_count = count;
+            flag->assigned = true;
+            break;
+        }
+        case KGFLAGS_FLAG_KIND_INT_ARRAY: {
+            int initial_cursor = _kgflags_g.arg_cursor;
+            int count = 0;
+            bool all_args_ok = true;
+            while (true) {
+                const char *val = _kgflags_peek_arg();
+                if (val == NULL || _kgflags_is_flag(val)) {
+                    break;
+                }
+                _kgflags_consume_arg();
+                bool ok = false;
+                _kgflags_parse_int(val, &ok);
+                if (!ok) {
+                    flag->error = true;
+                    _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_INT, flag->name, val);
+                    all_args_ok = false;
+                }
+                count++;
+            }
+            kgflags_int_array_t *arr = flag->result.int_array;
+            if (all_args_ok) {
+                arr->_items = _kgflags_g.argv + initial_cursor;
+                arr->_count = count;
+            }
+            flag->assigned = true;
+            break;
+        }
+        case KGFLAGS_FLAG_KIND_DOUBLE_ARRAY: {
+            int initial_cursor = _kgflags_g.arg_cursor;
+            int count = 0;
+            bool all_args_ok = true;
+            while (true) {
+                const char *val = _kgflags_peek_arg();
+                if (val == NULL || _kgflags_is_flag(val)) {
+                    break;
+                }
+                _kgflags_consume_arg();
+                bool ok = false;
+                _kgflags_parse_double(val, &ok);
+                if (!ok) {
+                    flag->error = true;
+                    _kgflags_add_error(KGFLAGS_ERROR_KIND_INVALID_DOUBLE, flag->name, val);
+                    all_args_ok = false;
+                }
+                count++;
+            }
+            kgflags_double_array_t *arr = flag->result.double_array;
+            if (all_args_ok) {
+                arr->_items = _kgflags_g.argv + initial_cursor;
+                arr->_count = count;
+            }
+            flag->assigned = true;
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+#endif
diff --git a/kgflags/readme.md b/kgflags/readme.md
new file mode 100644
index 000000000..a726dc0dd
--- /dev/null
+++ b/kgflags/readme.md
@@ -0,0 +1,75 @@
+## About
+kgflags is an easy to use command-line flag parsing library.
+
+## Features
+* Header-only (just copy kgflags.h).
+* Easy to use.
+* MIT licensed.
+* No dynamic allocations.
+* It supports strings, booleans, integers, double precision floats, string arrays, integer arrays, and double arrays.
+* Not relying on macros and non-standard features which makes it easy to debug and modify.
+* Test suites and examples.
+
+## Example
+```c
+// simple.c
+#define KGFLAGS_IMPLEMENTATION
+#include "kgflags.h"
+
+int main(int argc, char **argv) {
+    const char *to_print = NULL;  // guaranteed to be assigned only if kgflags_parse succeeds
+    kgflags_string("to-print", NULL, "String to print.", true, &to_print);
+
+    if (!kgflags_parse(argc, argv)) {
+        kgflags_print_errors();
+        kgflags_print_usage();
+        return 1;
+    }
+
+    puts(to_print);
+    return 0;
+}
+```
+
+```
+$ gcc simple.c -o simple
+$ ./simple --to-print "HELLO WORLD"
+HELLO WORLD
+```
+
+More examples can be found in [examples directory](http://github.com/kgabis/kgflags/tree/master/examples).
+
+## Installation
+Run:
+```
+git clone https://github.com/kgabis/kgflags.git
+```
+and copy kgflags.h to you source code tree.
+
+It behaves like most single header libraries - you have to declare KGFLAGS_IMPLEMENTATION in *one* C or C++ file *before* including it.
+
+```c
+#define KGFLAGS_IMPLEMENTATION
+#include "kgflags.h"
+```
+
+You can also customize max number of supported arguments/flags/errors by redefining KGFLAGS_MAX_NON_FLAG_ARGS, KGFLAGS_MAX_FLAGS and KGFLAGS_MAX_ERRORS (*before* including kgflags.h).
+
+## Testing
+Run ```pushd tests; ./run_tests.sh; popd``` to compile and run tests.
+
+## Limitations
+* It relies on global variables which means it's not thread safe. This shouldn't be an issue since argument parsing is done only once during startup of the application.
+* kgflags dosn't do any dynamic memory allocations. All string values returned are pointers to values given in argv array passed to ```kgflags_parse```. Same goes for default values, description strings and a prefix.
+
+## Contributing
+
+I will always merge *working* bug fixes. However, if you want to add something new to the API, please create an "issue" on github for this first so we can discuss if it should end up in the library before you start implementing it.  
+Remember to follow code's style and write appropriate tests.
+
+## Acknowledgements
+Many thanks to [Mateusz Belicki](https://github.com/mbelicki/) for all his suggestions and help.  
+kgflags is heavily inspired by Go's [flag package](https://golang.org/pkg/flag/).
+
+## License
+[The MIT License (MIT)](http://opensource.org/licenses/mit-license.php)
\ No newline at end of file
diff --git a/kgflags/tests/full_api_output b/kgflags/tests/full_api_output
new file mode 100644
index 000000000..7532cc5c0
--- /dev/null
+++ b/kgflags/tests/full_api_output
@@ -0,0 +1,31 @@
+Unrecognized flag: -extra-flag
+Unassigned required flag: -string
+Unassigned required flag: -bool
+Unassigned required flag: -int
+Unassigned required flag: -double
+Unassigned required flag: -string-array
+Unassigned required flag: -int-array
+Unassigned required flag: -double-array
+Usage of fullapi [-FLAGS]:
+Flags:
+	-string	(string)
+		String flag.
+
+	-bool, -no-bool	(boolean)
+		Boolean flag.
+
+	-int	(integer)
+		Integer flag.
+
+	-double	(float)
+		Double flag.
+
+	-string-array	(array of strings)
+		String array flag.
+
+	-int-array	(array of integers)
+		Int array flag.
+
+	-double-array	(array of floats)
+		Double array flag.
+
diff --git a/kgflags/tests/run_tests.sh b/kgflags/tests/run_tests.sh
new file mode 100755
index 000000000..a8e891af4
--- /dev/null
+++ b/kgflags/tests/run_tests.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+# set -xe
+
+TESTS_OK=true
+
+OUTDIR="output"
+
+function compile_and_run {
+	COMPILER=$1
+	FLAGS=$2
+	CFILE="tests.c"
+	OUTPUT="tests"
+
+	echo "Compiling and running ${CFILE} with ${COMPILER} ${FLAGS}:"
+
+	touch "${OUTDIR}/${OUTPUT}"
+	${COMPILER} ${FLAGS} "${CFILE}" -o "${OUTDIR}/${OUTPUT}"
+	"./${OUTDIR}/${OUTPUT}" > "${OUTDIR}/output_${COMPILER}"
+	RES=$?
+
+	if [ ${RES} != "0" ]; then
+		echo " FAIL"
+		cat "${OUTDIR}/output_${COMPILER}"
+		TESTS_OK=false
+	else
+		echo "	OK (output in ${OUTDIR}/output_${COMPILER})"
+	fi
+}
+
+if [ -d "${OUTDIR}" ]; then
+	rm -r "${OUTDIR}"
+fi
+
+mkdir "${OUTDIR}"
+
+CC="gcc"
+CFLAGS="-O0 -g -Wall -Wextra -std=c99 -pedantic-errors"
+
+CPPC="g++"
+CPPFLAGS="-O0 -g -Wall -Wextra -x c++ -Wno-c++11-compat-deprecated-writable-strings"
+
+compile_and_run ${CC} "${CFLAGS}"
+compile_and_run ${CPPC} "${CPPFLAGS}"
+
+for f in `ls ../examples/*.c`
+do
+	echo "Compiling ${f} with ${CC} ${CFLAGS}:"
+	fname=`basename ${f}`
+	${CC} ${CFLAGS} ${f} -o "${OUTDIR}/${fname}.out"
+	RES=$?
+
+	if [ ${RES} != "0" ]; then
+		echo " FAIL"
+		TESTS_OK=false
+	else
+		echo "	OK"
+	fi
+done
+
+echo "Compiling, running and comparing output of ../examples/full_api.c with ${CC} ${CFLAGS}:"
+${CC} ${CFLAGS} ../examples/full_api.c -o "${OUTDIR}/full_api"
+"./${OUTDIR}/full_api" -extra-flag 2> "${OUTDIR}/full_api_output"
+diff "${OUTDIR}/full_api_output" full_api_output
+RES=$?
+
+if [ ${RES} != "0" ]; then
+	echo " FAIL"
+	TESTS_OK=false
+else
+	echo "	OK"
+fi
+
+if [ "${TESTS_OK}" == true ]; then
+	echo "ALL TESTS SUCCEEDED"
+else
+	echo "TESTS FAILED"
+fi
+
diff --git a/kgflags/tests/tests.c b/kgflags/tests/tests.c
new file mode 100644
index 000000000..adbb55d39
--- /dev/null
+++ b/kgflags/tests/tests.c
@@ -0,0 +1,530 @@
+/*
+ Copyright (c) 2019 Krzysztof Gabis
+ 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.
+ */
+
+#include <stdbool.h>
+#include <math.h>
+#include <float.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define KGFLAGS_IMPLEMENTATION
+#include "../kgflags.h"
+
+#define TEST(DESC, A) printf("%4d: %-72s-", __LINE__, DESC);\
+if(A){puts(" OK");tests_passed++;}\
+else{puts(" FAIL");tests_failed++;}
+#define STREQ(A, B) ((A) && (B) ? strcmp((A), (B)) == 0 : 0)
+#define EPSILON 0.000001
+#define DBLEQ(a, b) (fabs((a) - (b)) < EPSILON)
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
+
+static void test_suite_expected(void);
+static void test_suite_uncommon(void);
+static void test_suite_errors(void);
+static void test_suite_int(void);
+static void test_suite_double(void);
+
+static bool test_kgflags_contains_error(_kgflags_error_kind_t kind);
+static void test_kgflags_reset(void);
+
+static int tests_passed;
+static int tests_failed;
+
+int main() {
+    test_suite_expected();
+    test_suite_uncommon();
+    test_suite_errors();
+    test_suite_int();
+    test_suite_double();
+    printf("Tests failed: %d\n", tests_failed);
+    printf("Tests passed: %d\n", tests_passed);
+    return tests_failed;
+}
+
+static void test_suite_expected() {
+    test_kgflags_reset();
+
+    char *argv[] = {
+        "app",
+        "non-flag-argument-0",
+        "--string", "lorem ipsum",
+        "--bool",
+        "--no-bool-2",
+        "--int", "123",
+        "non-flag-argument-1",
+        "--double", "123.3",
+        "non-flag-argument-2",
+        "--optional-assigned", "lorem ipsum",
+        "--string-array", "ala", "ma", "kota",
+        "--int-array", "1", "2", "3",
+        "--double-array", "1.23", "2.34", "3.45",
+    };
+
+    const char *stringval = NULL;
+    kgflags_string("string", "lorem", "String flag.", true, &stringval);
+
+    bool boolval = false;
+    kgflags_bool("bool", false, "Boolean flag.", true, &boolval);
+
+    bool bool2val = true;
+    kgflags_bool("bool-2", true, "Boolean flag.", true, &bool2val);
+
+    int intval = 0;
+    kgflags_int("int", 0, "Integer flag.", true, &intval);
+
+    double doubleval = 0;
+    kgflags_double("double", 0.0, "Double flag.", true, &doubleval);
+
+    kgflags_string_array_t string_arr;
+    kgflags_string_array("string-array", "String array flag.", true, &string_arr);
+
+    kgflags_int_array_t int_arr;
+    kgflags_int_array("int-array", "Int array flag.", true, &int_arr);
+
+    kgflags_double_array_t double_arr;
+    kgflags_double_array("double-array", "Double array flag.", true, &double_arr);
+
+    const char* optionalval = NULL;
+    kgflags_string("optional", "lorem", "Optional flag.", false, &optionalval);
+
+    const char* optionalval_assigned = NULL;
+    kgflags_string("optional-assigned", NULL, "Optional flag (assigned).", false, &optionalval_assigned);
+
+    bool ok = kgflags_parse(ARRAY_SIZE(argv), argv);
+
+    TEST("Parsing succeeded", ok);
+
+    if (!ok) {
+        return;
+    }
+
+    TEST("String argument", STREQ(stringval, "lorem ipsum"));
+    TEST("Optional string argument", STREQ(optionalval, "lorem"));
+    TEST("Bool argument", boolval == true);
+    TEST("Bool argument", bool2val == false);
+    TEST("Int argument", intval == 123);
+    TEST("Double argument", DBLEQ(doubleval, 123.3));
+    TEST("Optional assigned", STREQ(optionalval_assigned, "lorem ipsum"));
+
+    TEST("String array count", kgflags_string_array_get_count(&string_arr) == 3);
+    if (kgflags_string_array_get_count(&string_arr) == 3) {
+        TEST("Array argument [0]", kgflags_string_array_get_item(&string_arr, 0) == "ala");
+        TEST("Array argument [1]", kgflags_string_array_get_item(&string_arr, 1) == "ma");
+        TEST("Array argument [2]", kgflags_string_array_get_item(&string_arr, 2) == "kota");
+    }
+
+    TEST("Int array count", kgflags_int_array_get_count(&int_arr) == 3);
+    if (kgflags_int_array_get_count(&int_arr) == 3) {
+        TEST("Array argument [0]", kgflags_int_array_get_item(&int_arr, 0) == 1);
+        TEST("Array argument [1]", kgflags_int_array_get_item(&int_arr, 1) == 2);
+        TEST("Array argument [2]", kgflags_int_array_get_item(&int_arr, 2) == 3);
+    }
+
+    TEST("Double array count", kgflags_double_array_get_count(&double_arr) == 3);
+    if (kgflags_double_array_get_count(&double_arr) == 3) {
+        TEST("Array argument [0]", DBLEQ(kgflags_double_array_get_item(&double_arr, 0), 1.23));
+        TEST("Array argument [1]", DBLEQ(kgflags_double_array_get_item(&double_arr, 1), 2.34));
+        TEST("Array argument [2]", DBLEQ(kgflags_double_array_get_item(&double_arr, 2), 3.45));
+    }
+
+    int non_flag_count = kgflags_get_non_flag_args_count();
+    TEST("Non-flag args count", non_flag_count == 3);
+    if (non_flag_count == 3) {
+        TEST("Non-flag [0]", STREQ(kgflags_get_non_flag_arg(0), "non-flag-argument-0"));
+        TEST("Non-flag [1]", STREQ(kgflags_get_non_flag_arg(1), "non-flag-argument-1"));
+        TEST("Non-flag [2]", STREQ(kgflags_get_non_flag_arg(2), "non-flag-argument-2"));
+    }
+}
+
+static void test_suite_uncommon() {
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", };
+        TEST("No values", kgflags_parse(ARRAY_SIZE(argv), argv));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", };
+        const char* optionalval = NULL;
+        kgflags_string("optional", NULL, NULL, false, &optionalval);
+        TEST("No values, only optional", kgflags_parse(ARRAY_SIZE(argv), argv));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--string", "--val" };
+        const char *str = NULL;
+        kgflags_string("string", NULL, NULL, true, &str);
+        TEST("Value with prefix", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("Value is --val", STREQ(str, "--val"));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--", "val" };
+        const char *str = NULL;
+        kgflags_string("", NULL, NULL, true, &str);
+        TEST("Empty flag name", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("Value is val", STREQ(str, "val"));
+    }
+}
+
+static void test_suite_errors() {
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--string" };
+        const char *str = NULL;
+        kgflags_string("string", NULL, NULL, true, &str);
+        TEST("Missing value (string)", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_MISSING_VALUE set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_MISSING_VALUE));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--intval" };
+        int intval = 0;
+        kgflags_int("intval", 0, NULL, true, &intval);
+        TEST("Missing value (int)", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_MISSING_VALUE set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_MISSING_VALUE));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--double" };
+        double dblval = 0.0;
+        kgflags_double("double", 0.0, NULL, true, &dblval);
+        TEST("Missing value (double)", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_MISSING_VALUE set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_MISSING_VALUE));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--unknown", "val" };
+        TEST("Unknown flag", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_UNKNOWN_FLAG set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_UNKNOWN_FLAG));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "" };
+        double dblval = 0.0;
+        kgflags_double("non-flag", 0.0, NULL, true, &dblval);
+        TEST("Non-flag flag", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--invalid-int", "abc" };
+        int intval = 0;
+        kgflags_int("invalid-int", 0.0, NULL, true, &intval);
+        TEST("Invalid int", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_INVALID_INT set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_INVALID_INT));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--invalid-int", "123.3" };
+        int intval = 0;
+        kgflags_int("invalid-int", 0.0, NULL, true, &intval);
+        TEST("Invalid int (double)", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_INVALID_INT set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_INVALID_INT));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--invalid-int", "1", "2", "abc" };
+        kgflags_int_array_t arr;
+        kgflags_int_array("invalid-int", NULL, true, &arr);
+        TEST("Invalid int in array", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_INVALID_INT set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_INVALID_INT));
+        TEST("Array count == 0", kgflags_int_array_get_count(&arr) == 0);
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--invalid-double", "abc" };
+        double dblval = 0.0;
+        kgflags_double("invalid-double", 0.0, NULL, true, &dblval);
+        TEST("Invalid double", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_INVALID_DOUBLE set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_INVALID_DOUBLE));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--invalid-double", "1.23", "2.34", "abc" };
+        kgflags_double_array_t arr;
+        kgflags_double_array("invalid-double", NULL, true, &arr);
+        TEST("Invalid double in array", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_INVALID_DOUBLE set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_INVALID_DOUBLE));
+        TEST("Array count == 0", kgflags_double_array_get_count(&arr) == 0);
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "" };
+        for (int i = 0; i < (KGFLAGS_MAX_FLAGS + 1); i++) {
+            char *buf = (char*)malloc(256);
+            int *intval = (int*)malloc(sizeof(int));
+            sprintf(buf, "flag-%d", i);
+            kgflags_int(buf, 0.0, NULL, true, intval);
+        }
+        TEST("Too many flags", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_TOO_MANY_FLAGS));
+    }
+
+    {
+        test_kgflags_reset();
+        const char *str = NULL;
+        char *argv[] = { "", "--string", "val1", "--string", "val2" };
+        kgflags_string("string", NULL, NULL, true, &str);
+        TEST("Multiple assignment", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_MULTIPLE_ASSIGNMENT));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", };
+        const char *strval1 = NULL, *strval2 = NULL;
+        kgflags_string("string", NULL, NULL, true, &strval1);
+        kgflags_string("string", NULL, NULL, true, &strval2);
+        TEST("Duplicate flag", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_DUPLICATE_FLAG set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_DUPLICATE_FLAG));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", };
+        bool boolval = false;
+        kgflags_bool("no-bool", false, NULL, true, &boolval);
+        TEST("Bool flag with no- prefix", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_PREFIX_NO set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_PREFIX_NO));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--no-unknown", "val" };
+        const char *strval = NULL;
+        kgflags_string("unknown", NULL, NULL, true, &strval);
+        TEST("Unknown flag with no-prefix (non-boolean)", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 2);
+        TEST("KGFLAGS_ERROR_KIND_UNKNOWN_FLAG set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_UNKNOWN_FLAG));
+        TEST("KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_UNASSIGNED_FLAG));
+    }
+}
+
+void test_suite_int() {
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--intval", "-123" };
+        int intval = 0;
+        kgflags_int("intval", 0, NULL, true, &intval);
+        TEST("Negative value (int)", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("intval == -123", intval == -123);
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--intval", "+123" };
+        int intval = 0;
+        kgflags_int("intval", 0, NULL, true, &intval);
+        TEST("Positive value (int)", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("intval == +123", intval == 123);
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--intval", "123a" };
+        int intval = 0;
+        kgflags_int("intval", 0, NULL, true, &intval);
+        TEST("Invalid int value - extra character", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_INVALID_INT set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_INVALID_INT));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--intval", "abc" };
+        int intval = 0;
+        kgflags_int("intval", 0, NULL, true, &intval);
+        TEST("Invalid int value - string", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_INVALID_INT set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_INVALID_INT));
+    }
+
+    {
+        test_kgflags_reset();
+        int intmax = INT_MAX ;
+        char buf[256];
+        sprintf(buf, "%d", intmax);
+        char *argv[] = { "", "--intval", buf};
+        int intval = 0;
+        kgflags_int("intval", 0, NULL, true, &intval);
+        TEST("INT_MAX", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("intval == INT_MAX", intval == INT_MAX);
+    }
+
+    {
+        test_kgflags_reset();
+        unsigned int overflow = (unsigned int)INT_MAX + 1;
+        char buf[256];
+        sprintf(buf, "%ud", overflow);
+        char *argv[] = { "", "--intval", buf};
+        int intval = 0;
+        kgflags_int("intval", 0, NULL, true, &intval);
+        TEST("INT_MAX + 1", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_INVALID_INT set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_INVALID_INT));
+    }
+
+    {
+        test_kgflags_reset();
+        int intmin = INT_MIN ;
+        char buf[256];
+        sprintf(buf, "%d", intmin);
+        char *argv[] = { "", "--intval", buf};
+        int intval = 0;
+        kgflags_int("intval", 0, NULL, true, &intval);
+        TEST("INT_MIN", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("intval == INT_MIN", intval == INT_MIN);
+    }
+
+    {
+        test_kgflags_reset();
+        long long intmin = (long long)INT_MIN - 1;
+        char buf[256];
+        sprintf(buf, "%lld", intmin);
+        char *argv[] = { "", "--intval", buf};
+        int intval = 0;
+        kgflags_int("intval", 0, NULL, true, &intval);
+        TEST("INT_MIN - 1", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_INVALID_INT set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_INVALID_INT));
+    }
+}
+
+static void test_suite_double() {
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--dblval", "+123.4" };
+        double dblval = 0.0;
+        kgflags_double("dblval", 0.0, NULL, true, &dblval);
+        TEST("Positive value (double)", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("dblval == +123.4", DBLEQ(dblval, +123.4));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--dblval", "-123.4" };
+        double dblval = 0.0;
+        kgflags_double("dblval", 0.0, NULL, true, &dblval);
+        TEST("Negative value (double)", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("dblval == -123.4", DBLEQ(dblval, -123.4));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--dblval", "123" };
+        double dblval = 0.0;
+        kgflags_double("dblval", 0.0, NULL, true, &dblval);
+        TEST("Value without dot (double)", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("dblval == 123", DBLEQ(dblval, 123));
+    }
+
+    {
+        test_kgflags_reset();
+        double dblmax = DBL_MAX;
+        char buf[512];
+        sprintf(buf, "%f", dblmax);
+        char *argv[] = { "", "--dblval", buf};
+        double dblval = 0.0;
+        kgflags_double("dblval", 0.0, NULL, true, &dblval);
+        TEST("DBL_MAX (double)", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("dblval == DBL_MAX", DBLEQ(dblval, DBL_MAX));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--dblval", "NaN" };
+        double dblval = 0.0;
+        kgflags_double("dblval", 0.0, NULL, true, &dblval);
+        TEST("NaN", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("isnan", isnan(dblval));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--dblval", "Inf" };
+        double dblval = 0.0;
+        kgflags_double("dblval", 0.0, NULL, true, &dblval);
+        TEST("Inf", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("isinf", isinf(dblval));
+    }
+
+    {
+        test_kgflags_reset();
+        char *argv[] = { "", "--dblval", "-Inf" };
+        double dblval = 0.0;
+        kgflags_double("dblval", 0.0, NULL, true, &dblval);
+        TEST("-Inf", kgflags_parse(ARRAY_SIZE(argv), argv));
+        TEST("isinf", isinf(dblval));
+    }
+
+    {
+        test_kgflags_reset();
+        char buf[256];
+        sprintf(buf, "%f", NAN);
+        char *argv[] = { "", "--dblval", "123.4a" };
+        double dblval = 0.0;
+        kgflags_double("dblval", 0.0, NULL, true, &dblval);
+        TEST("Invalid double", kgflags_parse(ARRAY_SIZE(argv), argv) == false);
+        TEST("Errors count == 1", _kgflags_g.errors_count == 1);
+        TEST("KGFLAGS_ERROR_KIND_INVALID_DOUBLE set", test_kgflags_contains_error(KGFLAGS_ERROR_KIND_INVALID_DOUBLE));
+    }
+}
+
+static bool test_kgflags_contains_error(_kgflags_error_kind_t kind) {
+    for (int i = 0; i < _kgflags_g.errors_count; i++) {
+        _kgflags_error_t *err = &_kgflags_g.errors[i];
+        if (err->kind == kind) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static void test_kgflags_reset() {
+    memset(&_kgflags_g, 0, sizeof(_kgflags_g));
+}
diff --git a/kgflags/tests/update_full_api_output.sh b/kgflags/tests/update_full_api_output.sh
new file mode 100755
index 000000000..312f5baa8
--- /dev/null
+++ b/kgflags/tests/update_full_api_output.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# set -xe
+
+CC="gcc"
+CFLAGS="-O0 -g -Wall -Wextra -std=c99 -pedantic-errors"
+
+echo "Compiling, running and saving output of ../examples/full_api.c with ${CC} ${CFLAGS}"
+${CC} ${CFLAGS} ../examples/full_api.c -o full_api
+"./full_api" -extra-flag 2> "full_api_output"
+rm full_api
\ No newline at end of file
-- 
GitLab