kyaa/kyaa.h

119 lines
3.8 KiB
C
Raw Normal View History

2016-08-18 19:46:44 -07:00
/* kyaa.h - macro hacks for handling main() arguments
2017-04-01 19:24:19 -07:00
This is free and unencumbered software released into the public domain.
Refer to kyaa.md for documentation.
2016-08-18 19:46:44 -07:00
*/
2019-06-25 17:26:22 -07:00
#ifndef KYAA_ONCE
#define KYAA_ONCE
2016-08-18 19:46:44 -07:00
2019-06-25 17:26:22 -07:00
/* set some sane defaults. */
2016-08-18 19:46:44 -07:00
#ifndef KYAA_OKAY
#define KYAA_OKAY 0
#endif
2019-06-25 17:26:22 -07:00
#ifndef KYAA_FAIL
#define KYAA_FAIL 1
2016-08-18 19:46:44 -07:00
#endif
2019-06-25 17:26:22 -07:00
#ifndef KYAA_OUT
#define KYAA_OUT(...) printf(__VA_ARGS__)
2016-08-18 19:46:44 -07:00
#endif
2019-06-25 17:26:22 -07:00
#ifndef KYAA_ERR
#define KYAA_ERR(...) fprintf(stderr, __VA_ARGS__)
#endif
#define KYAA_IS_LONG(arg, name) \
(strncmp(arg, "--" name, strlen("--" name)) == 0 && \
(arg[strlen("--" name)] == '\0' || arg[strlen("--" name)] == '='))
2016-08-18 19:46:44 -07:00
#define KYAA_SETUP \
2017-03-30 23:29:13 -07:00
if (argc <= 0 || argv == NULL || argv[0] == NULL) { \
2019-06-25 17:26:22 -07:00
KYAA_ERR("malformed argc/argv\n"); \
return KYAA_FAIL; \
2016-08-18 19:46:44 -07:00
} \
2019-06-25 17:26:22 -07:00
const char *kyaa_name = argv[0]; \
2016-08-18 19:46:44 -07:00
bool kyaa_read_stdin = false; \
2019-06-25 17:26:22 -07:00
char kyaa_char = '\0'; \
bool kyaa_parsing = true; \
bool kyaa_skip = false; \
2016-08-18 19:46:44 -07:00
#define KYAA_LOOP \
KYAA_SETUP \
2019-06-25 17:26:22 -07:00
for (int kyaa_iter = 1; kyaa_iter < argc; kyaa_iter++) \
2016-08-18 19:46:44 -07:00
#define KYAA_BEGIN \
2019-06-25 17:26:22 -07:00
const char *kyaa_arg = argv[kyaa_iter]; \
if (kyaa_parsing && (kyaa_skip || kyaa_arg[0] == '-')) { \
if (!kyaa_skip && kyaa_arg[1] == '-' && kyaa_arg[2] == '\0') { \
kyaa_parsing = false; \
2016-08-18 19:46:44 -07:00
continue; \
} \
2019-06-25 17:26:22 -07:00
if (!kyaa_skip && kyaa_arg[1] == '\0') kyaa_read_stdin = true; \
else { \
/* case: kyaa_skip: kyaa_arg is at least 1 char long. */ \
/* case: !kyaa_skip: kyaa_arg is at least 3 chars long. */ \
const char *kyaa_etc = kyaa_skip ? kyaa_arg : kyaa_arg + 2; \
const char *kyaa_equals = kyaa_skip ? NULL : strchr(kyaa_etc, '='); \
2016-08-18 19:46:44 -07:00
bool kyaa_helping = false; \
bool kyaa_any = false; \
2019-06-25 17:26:22 -07:00
if (!kyaa_skip) { \
if (kyaa_arg[1] != '-') { \
kyaa_char = kyaa_arg[1]; \
if (kyaa_arg[2] == '\0') kyaa_etc = NULL; \
} else if (kyaa_equals == NULL) kyaa_etc = NULL; \
else kyaa_etc = kyaa_equals + 1; \
if (strcmp(kyaa_arg, "--help") == 0) kyaa_char = 'h'; \
if (kyaa_char == 'h') { \
KYAA_OUT("usage:\n"); \
kyaa_helping = true; \
} \
2016-08-18 19:46:44 -07:00
} \
if (0) { \
#define KYAA_END \
} \
if (!kyaa_any && !kyaa_helping) { \
2019-06-25 17:26:22 -07:00
if (kyaa_char) KYAA_ERR("unknown flag: -%c\n", kyaa_char); \
else KYAA_ERR("unknown flag: %s\n", kyaa_arg); \
return KYAA_FAIL; \
2016-08-18 19:46:44 -07:00
} \
if (kyaa_helping) { \
return KYAA_OKAY; \
} \
2019-06-25 17:26:22 -07:00
kyaa_skip = false; \
kyaa_char = '\0'; \
2016-08-18 19:46:44 -07:00
continue; \
} \
} \
#define KYAA_DESCRIBE(c, name, description) \
2019-06-25 17:26:22 -07:00
KYAA_OUT(" -%c --%s\n%s\n", c, name, description) \
2016-08-18 19:46:44 -07:00
#define KYAA_FLAG(c, name, description) \
} \
2019-06-25 17:26:22 -07:00
if (kyaa_helping) KYAA_DESCRIBE(c, name, description); \
else if (kyaa_char == c || KYAA_IS_LONG(kyaa_arg, name)) { \
kyaa_char = c; \
2016-08-18 19:46:44 -07:00
kyaa_any = true; \
#define KYAA_FLAG_ARG(c, name, description) \
} \
2019-06-25 17:26:22 -07:00
if (kyaa_helping) KYAA_DESCRIBE(c, name, description); \
else if (kyaa_char == c || KYAA_IS_LONG(kyaa_arg, name)) { \
if (kyaa_etc == NULL) { \
kyaa_skip = true; \
if (kyaa_iter + 1 == argc || argv[kyaa_iter + 1] == NULL) { \
KYAA_ERR("expected an argument for --%s (-%c)\n", name, c); \
return KYAA_FAIL; \
2016-08-18 19:46:44 -07:00
} \
2019-06-25 17:26:22 -07:00
kyaa_char = c; \
2016-08-18 19:46:44 -07:00
continue; \
} \
2019-06-25 17:26:22 -07:00
kyaa_char = c; \
2016-08-18 19:46:44 -07:00
kyaa_any = true; \
#define KYAA_HELP(description) \
} \
if (kyaa_helping) { \
2019-06-25 17:26:22 -07:00
if (description != NULL) KYAA_OUT("%s\n", description); \
2016-08-18 19:46:44 -07:00
2019-06-25 17:26:22 -07:00
#endif /* KYAA_ONCE */