resynth/kyaa.h
2016-10-31 06:32:12 -07:00

122 lines
3.8 KiB
C

/* kyaa.h - macro hacks for handling main() arguments
license: public domain or whatever.
documentation is kept separate in kyaa.md
*/
#pragma once
#ifndef KYAA_OKAY
#define KYAA_OKAY 0
#endif
#ifndef KYAA_ERROR
#define KYAA_ERROR 1
#endif
#ifndef KYAA_ITER
#define KYAA_ITER i
#endif
#define KYAA_SETUP \
/* dumb sanity checks */ \
if (argc <= 0 || argv == NULL || argv[0] == NULL) { \
fprintf(stderr, "You've met with a terrible fate.\n"); \
return KYAA_ERROR; \
} \
char *kyaa_name = argv[0]; \
bool kyaa_read_stdin = false; \
char kyaa_flag = '\0'; \
bool kyaa_keep_parsing = true; \
bool kyaa_parse_next = false; \
#define KYAA_LOOP \
KYAA_SETUP \
for (int KYAA_ITER = 1; KYAA_ITER < argc; KYAA_ITER++) \
#define KYAA_BEGIN \
char *kyaa_arg = argv[KYAA_ITER]; \
if (kyaa_keep_parsing && (kyaa_parse_next || kyaa_arg[0] == '-')) { \
if (!kyaa_parse_next && kyaa_arg[1] == '-' && kyaa_arg[2] == '\0') { \
kyaa_keep_parsing = false; \
continue; \
} \
if (!kyaa_parse_next && kyaa_arg[1] == '\0') { \
kyaa_read_stdin = true; \
} else { \
/* case: kyaa_parse_next: arg is at least 1 char initialized. */ \
/* case: !kyaa_parse_next: arg is at least 3 chars initialized. */ \
char *kyaa_etc = kyaa_parse_next ? kyaa_arg : kyaa_arg + 2; \
bool kyaa_no_more = false; \
bool kyaa_helping = false; \
bool kyaa_any = false; \
if (!kyaa_parse_next && kyaa_arg[1] != '-') { \
kyaa_flag = kyaa_arg[1]; \
kyaa_no_more = kyaa_arg[2] == '\0'; \
} \
if (kyaa_flag == 'h' || !strcmp(kyaa_arg, "--help")) { \
printf("usage:\n"); \
kyaa_helping = true; \
} \
if (0) { \
#define KYAA_END \
} \
if (!kyaa_any && !kyaa_helping) { \
if (kyaa_flag) { \
fprintf(stderr, "unknown flag: -%c\n", kyaa_flag); \
} else { \
fprintf(stderr, "unknown flag: %s\n", kyaa_arg); \
} \
return KYAA_ERROR; \
} \
if (kyaa_helping) { \
return KYAA_OKAY; \
} \
kyaa_parse_next = false; \
kyaa_flag = '\0'; \
continue; \
} \
} \
#define KYAA_DESCRIBE(c, name, description) \
printf(" -%c --%s\n%s\n", c, name, description) \
#define KYAA_FLAG(c, name, description) \
} \
if (kyaa_helping) { \
KYAA_DESCRIBE(c, name, description); \
} else if (kyaa_flag == c || !strcmp(kyaa_arg, "--"name)) { \
kyaa_flag = c; \
kyaa_any = true; \
#define KYAA_FLAG_ARG(c, name, description) \
} \
if (kyaa_helping) { \
KYAA_DESCRIBE(c, name, description); \
} else if (kyaa_flag == c || !strcmp(kyaa_arg, "--"name)) { \
if (kyaa_no_more || kyaa_flag != c) { \
kyaa_parse_next = true; \
if (KYAA_ITER + 1 == argc || argv[KYAA_ITER + 1][0] == '\0') { \
fprintf(stderr, "expected an argument for --%s (-%c)\n", name, c); \
return KYAA_ERROR; \
} \
kyaa_flag = c; \
continue; \
} \
kyaa_flag = c; \
kyaa_any = true; \
#define KYAA_FLAG_LONG(c, name, description) \
KYAA_FLAG_ARG(c, name, description) \
errno = 0; \
long kyaa_flag_arg = strtol(kyaa_etc, NULL, 0); \
if (errno) { \
perror(NULL); \
return KYAA_ERROR; \
} \
#define KYAA_HELP(description) \
} \
if (kyaa_helping) { \
if (description != NULL) { \
printf("%s\n", description); \
} \