diff --git a/kyaa.h b/kyaa.h index 2f825a3..a2d7f5e 100644 --- a/kyaa.h +++ b/kyaa.h @@ -1,113 +1,118 @@ /* kyaa.h - macro hacks for handling main() arguments This is free and unencumbered software released into the public domain. - Refer to kyaa.md for documentation. + For more information, please refer to */ -#pragma once +#ifndef KYAA_ONCE +#define KYAA_ONCE +/* set some sane defaults. */ #ifndef KYAA_OKAY #define KYAA_OKAY 0 #endif -#ifndef KYAA_ERROR -#define KYAA_ERROR 1 +#ifndef KYAA_FAIL +#define KYAA_FAIL 1 #endif -#ifndef KYAA_ITER -#define KYAA_ITER i +#ifndef KYAA_OUT +#define KYAA_OUT(...) printf(__VA_ARGS__) +#endif +#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)] == '=')) + #define KYAA_SETUP \ - /* sanity checks */ \ if (argc <= 0 || argv == NULL || argv[0] == NULL) { \ - fprintf(stderr, "You've met with a terrible fate.\n"); \ - return KYAA_ERROR; \ + KYAA_ERR("malformed argc/argv\n"); \ + return KYAA_FAIL; \ } \ - char *kyaa_name = argv[0]; \ + const char *kyaa_name = argv[0]; \ bool kyaa_read_stdin = false; \ - char kyaa_flag = '\0'; \ - bool kyaa_keep_parsing = true; \ - bool kyaa_parse_next = false; \ + char kyaa_char = '\0'; \ + bool kyaa_parsing = true; \ + bool kyaa_skip = false; \ #define KYAA_LOOP \ KYAA_SETUP \ - for (int KYAA_ITER = 1; KYAA_ITER < argc; KYAA_ITER++) \ + 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; \ + 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; \ 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; \ + 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, '='); \ 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 (!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; \ + } \ } \ 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_char) KYAA_ERR("unknown flag: -%c\n", kyaa_char); \ + else KYAA_ERR("unknown flag: %s\n", kyaa_arg); \ + return KYAA_FAIL; \ } \ if (kyaa_helping) { \ return KYAA_OKAY; \ } \ - kyaa_parse_next = false; \ - kyaa_flag = '\0'; \ + kyaa_skip = false; \ + kyaa_char = '\0'; \ continue; \ } \ } \ #define KYAA_DESCRIBE(c, name, description) \ - printf(" -%c --%s\n%s\n", c, name, description) \ + KYAA_OUT(" -%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; \ + if (kyaa_helping) KYAA_DESCRIBE(c, name, description); \ + else if (kyaa_char == c || KYAA_IS_LONG(kyaa_arg, name)) { \ + kyaa_char = 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; \ + 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; \ } \ - kyaa_flag = c; \ + kyaa_char = c; \ continue; \ } \ - kyaa_flag = c; \ + kyaa_char = c; \ kyaa_any = true; \ #define KYAA_HELP(description) \ } \ if (kyaa_helping) { \ - if (description != NULL) { \ - printf("%s\n", description); \ - } \ + if (description != NULL) KYAA_OUT("%s\n", description); \ +#endif /* KYAA_ONCE */ diff --git a/kyaa_extra.h b/kyaa_extra.h index 77869f4..e16c59c 100644 --- a/kyaa_extra.h +++ b/kyaa_extra.h @@ -1,9 +1,12 @@ /* kyaa_extra.h - extensions to kyaa for parsing arguments. This is free and unencumbered software released into the public domain. - Refer to kyaa.md for documentation. + For more information, please refer to */ -static char *kyaa_skip_spaces(char *str) { +#ifndef KYAA_EXTRA +#define KYAA_EXTRA + +static const char *kyaa_skip_spaces(const char *str) { /* iterates str to first non-space character according to the C locale */ while (*str != '\0') { switch (*str) { @@ -19,8 +22,8 @@ static char *kyaa_skip_spaces(char *str) { return str; } -static const char *kyaa__base_2(char **p_str, long *p_out) { - char *str = *p_str; +static const char *kyaa__base_2(const char **p_str, long *p_out) { + const char *str = *p_str; long out = *p_out; for (char c; (c = *str) != '\0'; str++) { switch (c) { @@ -47,8 +50,8 @@ exit: return NULL; } -static const char *kyaa__base_8(char **p_str, long *p_out) { - char *str = *p_str; +static const char *kyaa__base_8(const char **p_str, long *p_out) { + const char *str = *p_str; long out = *p_out; for (char c; (c = *str) != '\0'; str++) { switch (c) { @@ -75,8 +78,8 @@ exit: return NULL; } -static const char *kyaa__base_10(char **p_str, long *p_out) { - char *str = *p_str; +static const char *kyaa__base_10(const char **p_str, long *p_out) { + const char *str = *p_str; long out = *p_out; for (char c; (c = *str) != '\0'; str++) { switch (c) { @@ -102,8 +105,8 @@ exit: return NULL; } -static const char *kyaa__base_16(char **p_str, long *p_out) { - char *str = *p_str; +static const char *kyaa__base_16(const char **p_str, long *p_out) { + const char *str = *p_str; long out = *p_out; for (char c; (c = *str) != '\0'; str++) { switch (c) { @@ -143,7 +146,7 @@ exit: return NULL; } -static const char *kyaa_str_to_long(char *str, long *p_out) { +static const char *kyaa_str_to_long(const char *str, long *p_out) { /* returns error message or NULL */ long out = 0; int base = 10; @@ -202,10 +205,11 @@ static const char *kyaa_str_to_long(char *str, long *p_out) { #define KYAA_FLAG_LONG(c, name, description) \ KYAA_FLAG_ARG(c, name, description) \ - long kyaa_flag_arg; \ - const char *err = kyaa_str_to_long(kyaa_etc, &kyaa_flag_arg); \ + long kyaa_long_value; \ + const char *err = kyaa_str_to_long(kyaa_etc, &kyaa_long_value); \ if (err) { \ - fprintf(stderr, "%s\n", err); \ - return KYAA_ERROR; \ + KYAA_ERR("%s\n", err); \ + return KYAA_FAIL; \ } \ +#endif /* KYAA_EXTRA */ diff --git a/resynth.c b/resynth.c index 19dfdef..a2d3604 100644 --- a/resynth.c +++ b/resynth.c @@ -484,39 +484,39 @@ int main(int argc, char *argv[]) { KYAA_FLAG_LONG('a', "autism", " sensitivity to outliers\n" " range: [0,256]; default: 32") - parameters.autism = (double)(kyaa_flag_arg) / 256.; + parameters.autism = (double)(kyaa_long_value) / 256.; KYAA_FLAG_LONG('N', "neighbors", " points to use when sampling\n" " range: [0,1024]; default: 29") - parameters.neighbors = kyaa_flag_arg; + parameters.neighbors = kyaa_long_value; KYAA_FLAG_LONG('R', "circle-radius", " circle neighborhood radius\n" " range: [1,128]; default: [n/a]") - int radius = kyaa_flag_arg; + int radius = kyaa_long_value; radius = CLAMP(radius, 1, (int)(LEN(disc00))); parameters.neighbors = disc00[radius - 1]; KYAA_FLAG_LONG('M', "tries", " random points added to candidates\n" " range: [0,65536]; default: 192") - parameters.tries = kyaa_flag_arg; + parameters.tries = kyaa_long_value; KYAA_FLAG_LONG('m', "magic", " magic constant, affects iterations\n" " range: [0,255]; default: 192") - parameters.magic = kyaa_flag_arg; + parameters.magic = kyaa_long_value; KYAA_FLAG_LONG('s', "scale", " output size multiplier; negative values set width and height\n" " range: [-8192,32]; default: 1") - scale = kyaa_flag_arg; + scale = kyaa_long_value; KYAA_FLAG_LONG('S', "seed", " initial RNG value\n" " default: 0 [time(0)]") - seed = (unsigned long) kyaa_flag_arg; + seed = (unsigned long) kyaa_long_value; KYAA_HELP(" {files...}\n" " image files to open, resynthesize, and save as {filename}.resynth.png\n"