diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | color.h | 8 | ||||
-rw-r--r-- | config.c | 208 | ||||
-rw-r--r-- | config.h | 22 | ||||
-rw-r--r-- | nebula2.c | 220 |
5 files changed, 243 insertions, 219 deletions
@@ -2,8 +2,8 @@ CC=gcc CFLAGS=-Wall -Werror -pedantic -std=c99 -static LIBS=-Liniparser -liniparser -nebula2: nebula2.o iniparser/libiniparser.a - $(CC) $(CFLAGS) -o nebula2 nebula2.o iniparser/libiniparser.a +nebula2: nebula2.o config.o iniparser/libiniparser.a + $(CC) $(CFLAGS) -o nebula2 nebula2.o config.o iniparser/libiniparser.a iniparser/libiniparser.a: make -C iniparser libiniparser.a @@ -0,0 +1,8 @@ +#ifndef _nebula2_color_h_ +#define _nebula2_color_h_ + +typedef struct { + int r, g, b; +} color_t; + +#endif
\ No newline at end of file diff --git a/config.c b/config.c new file mode 100644 index 0000000..032ea6a --- /dev/null +++ b/config.c @@ -0,0 +1,208 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "config.h" +#include "color.h" + +#include "iniparser/src/iniparser.h" + +void +conf_destroy(config_t* conf) { + if(conf->iters) { + free(conf->iters); + } + if(conf->colors) { + free(conf->colors); + } + free(conf); +} + +static int +parse_color(dictionary* ini, char* key, color_t* col) { + char r[3]; + char g[3]; + char b[3]; + char* endptr; + char* s = iniparser_getstring(ini, key, ""); + + if(strlen(s) != 6) { + fprintf(stderr, "Config value '%s' is not a color or is missing.\n", key); + return 0; + } + + memcpy(r, s, 2); + memcpy(g, s + 2, 2); + memcpy(b, s + 4, 2); + r[2] = '\0'; + g[2] = '\0'; + b[2] = '\0'; + + col->r = strtol(r, &endptr, 16); + if(*endptr != '\0') { + fprintf(stderr, "Config value '%s' is not a color.\n", key); + return 0; + } + col->g = strtol(g, &endptr, 16); + if(*endptr != '\0') { + fprintf(stderr, "Config value '%s' is not a color.\n", key); + return 0; + } + col->b = strtol(b, &endptr, 16); + if(*endptr != '\0') { + fprintf(stderr, "Config value '%s' is not a color.\n", key); + return 0; + } + + return 1; +} + +#define NAMEBUF_SIZE 32 + +static int +conf_get_int(dictionary* ini, char* key, int* val) { + if(!iniparser_find_entry(ini, key)) { + fprintf(stderr, "Missing config key: %s\n", key); + return 0; + } + + *val = iniparser_getint(ini, key, -1); + + if(*val <= 0) { + fprintf(stderr, "Value for key '%s' is invalid.\n", key); + return 0; + } + + return 1; +} + +static char* +conf_get_string(dictionary* ini, char* key, char* def) { + char* _s; + char* s; + size_t l; + + _s = iniparser_getstring(ini, key, def); + + l = strlen(_s) + 1; + if(!(s = malloc(sizeof(char) * l))) { + return NULL; + } + + return strcpy(s, _s); +} + +int +conf_load(char* path, config_t** conf) { + int i; + dictionary* ini = NULL; + char namebuf[NAMEBUF_SIZE]; + + if(!(*conf = malloc(sizeof(config_t)))) { + fputs("Could not allocate memory.\n", stderr); + goto failed; + } + + (*conf)->iters = NULL; + (*conf)->colors = NULL; + (*conf)->statefile = NULL; + (*conf)->output = NULL; + + if(!(ini = iniparser_load(path))) { + fputs("Could not parse ini file.\n", stderr); + goto failed; + } + + if( + (!conf_get_int(ini, "nebula2:width", &((*conf)->width))) || + (!conf_get_int(ini, "nebula2:height", &((*conf)->height))) || + (!conf_get_int(ini, "nebula2:jobsize", &((*conf)->jobsize))) || + (!conf_get_int(ini, "nebula2:jobs", &((*conf)->jobs))) || + (!conf_get_int(ini, "nebula2:procn", &((*conf)->procn)))) { + goto failed; + } + + if(!((*conf)->statefile = conf_get_string(ini, "nebula2:statefile", ""))) { + goto failed; + } + if(!((*conf)->output = conf_get_string(ini, "nebula2:output", ""))) { + goto failed; + } + + for((*conf)->iters_n = 0;; ((*conf)->iters_n)++) { + if(snprintf(namebuf, NAMEBUF_SIZE, "nebula2:iter%d", (*conf)->iters_n) < 0) { + fputs("Error while counting iterX values.\n", stderr); + goto failed; + } + + if(!iniparser_find_entry(ini, namebuf)) { + break; + } + } + + if((*conf)->iters_n == 0) { + fputs("Need at least one iterX value.\n", stderr); + goto failed; + } + + if(!((*conf)->iters = malloc(sizeof(int) * ((*conf)->iters_n)))) { + fputs("Could not allocate memory.\n", stderr); + goto failed; + } + if(!((*conf)->colors = malloc(sizeof(color_t) * ((*conf)->iters_n)))) { + fputs("Could not allocate memory.\n", stderr); + goto failed; + } + + for(i = 0; i < (*conf)->iters_n; i++) { + if(snprintf(namebuf, NAMEBUF_SIZE, "nebula2:iter%d", i) < 0) { + fputs("Error while reading iterX values.\n", stderr); + goto failed; + } + + if(!conf_get_int(ini, namebuf, &((*conf)->iters[i]))) { + goto failed; + } + + if(snprintf(namebuf, NAMEBUF_SIZE, "nebula2:color%d", i) < 0) { + fputs("Error while reading colorX values.\n", stderr); + goto failed; + } + + if(!parse_color(ini, namebuf, &((*conf)->colors[i]))) { + goto failed; + } + } + + iniparser_freedict(ini); + return 1; + +failed: + if(*conf) { + conf_destroy(*conf); + *conf = NULL; + } + if(ini) { + iniparser_freedict(ini); + } + return 0; +} + +void +conf_print(config_t* conf) { + int i; + color_t col; + + printf("width: %d\n", conf->width); + printf("height: %d\n", conf->height); + printf("jobsize: %d\n", conf->jobsize); + printf("jobs: %d\n", conf->jobs); + printf("procn: %d\n", conf->procn); + printf("statefile: %s\n", conf->statefile); + printf("output: %s\n", conf->output); + + for(i = 0; i < conf->iters_n; i++) { + col = conf->colors[i]; + printf("Iteration %d: %d, %02x%02x%02x\n", i, conf->iters[i], col.r, col.g, col.b); + } +} diff --git a/config.h b/config.h new file mode 100644 index 0000000..11923eb --- /dev/null +++ b/config.h @@ -0,0 +1,22 @@ +#ifndef _nebula2_config_h_ +#define _nebula2_config_h_ + +#include "color.h" + +typedef struct { + int width, height; + int jobsize, jobs, procn; + + char* statefile; + char* output; + + int iters_n; + int* iters; + color_t* colors; +} config_t; + +extern void conf_destroy(config_t* conf); +extern int conf_load(char* path, config_t** conf); +extern void conf_print(config_t* conf); + +#endif @@ -2,225 +2,11 @@ #include <stdlib.h> #include <string.h> -#include "iniparser/src/iniparser.h" - -typedef struct { - int r, g, b; -} color_t; - -typedef struct { - int width, height; - int jobsize, jobs, procn; - - char* statefile; - char* output; - - int iters_n; - int* iters; - color_t* colors; -} config_t; - -void -usage(void) {} - -void -conf_destroy(config_t* conf) { - if(conf->iters) { - free(conf->iters); - } - if(conf->colors) { - free(conf->colors); - } - free(conf); -} - -int -parse_color(dictionary* ini, char* key, color_t* col) { - char r[3]; - char g[3]; - char b[3]; - char* endptr; - char* s = iniparser_getstring(ini, key, ""); - - if(strlen(s) != 6) { - fprintf(stderr, "Config value '%s' is not a color or is missing.\n", key); - return 0; - } - - memcpy(r, s, 2); - memcpy(g, s + 2, 2); - memcpy(b, s + 4, 2); - r[2] = '\0'; - g[2] = '\0'; - b[2] = '\0'; - - col->r = strtol(r, &endptr, 16); - if(*endptr != '\0') { - fprintf(stderr, "Config value '%s' is not a color.\n", key); - return 0; - } - col->g = strtol(g, &endptr, 16); - if(*endptr != '\0') { - fprintf(stderr, "Config value '%s' is not a color.\n", key); - return 0; - } - col->b = strtol(b, &endptr, 16); - if(*endptr != '\0') { - fprintf(stderr, "Config value '%s' is not a color.\n", key); - return 0; - } - - return 1; -} - -#define NAMEBUF_SIZE 32 - -int -conf_get_int(dictionary* ini, char* key, int* val) { - if(!iniparser_find_entry(ini, key)) { - fprintf(stderr, "Missing config key: %s\n", key); - return 0; - } - - *val = iniparser_getint(ini, key, -1); - - if(*val <= 0) { - fprintf(stderr, "Value for key '%s' is invalid.\n", key); - return 0; - } - - return 1; -} - -char* -conf_get_string(dictionary* ini, char* key, char* def) { - char* _s; - char* s; - size_t l; - - _s = iniparser_getstring(ini, key, def); - - l = strlen(_s) + 1; - if(!(s = malloc(sizeof(char) * l))) { - return NULL; - } - - return strcpy(s, _s); -} - -int -conf_load(char* path, config_t** conf) { - int i; - dictionary* ini = NULL; - char namebuf[NAMEBUF_SIZE]; - - if(!(*conf = malloc(sizeof(config_t)))) { - fputs("Could not allocate memory.\n", stderr); - goto failed; - } - - (*conf)->iters = NULL; - (*conf)->colors = NULL; - (*conf)->statefile = NULL; - (*conf)->output = NULL; - - if(!(ini = iniparser_load(path))) { - fputs("Could not parse ini file.\n", stderr); - goto failed; - } - - if( - (!conf_get_int(ini, "nebula2:width", &((*conf)->width))) || - (!conf_get_int(ini, "nebula2:height", &((*conf)->height))) || - (!conf_get_int(ini, "nebula2:jobsize", &((*conf)->jobsize))) || - (!conf_get_int(ini, "nebula2:jobs", &((*conf)->jobs))) || - (!conf_get_int(ini, "nebula2:procn", &((*conf)->procn)))) { - goto failed; - } - - if(!((*conf)->statefile = conf_get_string(ini, "nebula2:statefile", ""))) { - goto failed; - } - if(!((*conf)->output = conf_get_string(ini, "nebula2:output", ""))) { - goto failed; - } - - for((*conf)->iters_n = 0;; ((*conf)->iters_n)++) { - if(snprintf(namebuf, NAMEBUF_SIZE, "nebula2:iter%d", (*conf)->iters_n) < 0) { - fputs("Error while counting iterX values.\n", stderr); - goto failed; - } - - if(!iniparser_find_entry(ini, namebuf)) { - break; - } - } - - if((*conf)->iters_n == 0) { - fputs("Need at least one iterX value.\n", stderr); - goto failed; - } - - if(!((*conf)->iters = malloc(sizeof(int) * ((*conf)->iters_n)))) { - fputs("Could not allocate memory.\n", stderr); - goto failed; - } - if(!((*conf)->colors = malloc(sizeof(color_t) * ((*conf)->iters_n)))) { - fputs("Could not allocate memory.\n", stderr); - goto failed; - } - - for(i = 0; i < (*conf)->iters_n; i++) { - if(snprintf(namebuf, NAMEBUF_SIZE, "nebula2:iter%d", i) < 0) { - fputs("Error while reading iterX values.\n", stderr); - goto failed; - } - - if(!conf_get_int(ini, namebuf, &((*conf)->iters[i]))) { - goto failed; - } - - if(snprintf(namebuf, NAMEBUF_SIZE, "nebula2:color%d", i) < 0) { - fputs("Error while reading colorX values.\n", stderr); - goto failed; - } - - if(!parse_color(ini, namebuf, &((*conf)->colors[i]))) { - goto failed; - } - } - - iniparser_freedict(ini); - return 1; - -failed: - if(*conf) { - conf_destroy(*conf); - *conf = NULL; - } - if(ini) { - iniparser_freedict(ini); - } - return 0; -} +#include "config.h" void -conf_print(config_t* conf) { - int i; - color_t col; - - printf("width: %d\n", conf->width); - printf("height: %d\n", conf->height); - printf("jobsize: %d\n", conf->jobsize); - printf("jobs: %d\n", conf->jobs); - printf("procn: %d\n", conf->procn); - printf("statefile: %s\n", conf->statefile); - printf("output: %s\n", conf->output); - - for(i = 0; i < conf->iters_n; i++) { - col = conf->colors[i]; - printf("Iteration %d: %d, %02x%02x%02x\n", i, conf->iters[i], col.r, col.g, col.b); - } +usage(void) { + fputs("nebula2 needs the name of a config file as 1st argument.\n", stderr); } int |