# HG changeset patch # User John Tsiombikas # Date 1347245883 -10800 # Node ID 4f36bbbcc82f66abb674f588fcbac19f5558a8a2 # Parent 1b0db53d5b5bf260db7173fc5016233ee411256f really started writting the parser... god I hate ad-hoc parsing... diff -r 1b0db53d5b5b -r 4f36bbbcc82f src/pattr.c --- a/src/pattr.c Thu Sep 06 02:32:58 2012 +0300 +++ b/src/pattr.c Mon Sep 10 05:58:03 2012 +0300 @@ -5,6 +5,22 @@ #include "pattr.h" #include "psys_gl.h" +enum { + OPT_STR, + OPT_NUM, + OPT_NUM_RANGE, + OPT_VEC, + OPT_VEC_RANGE +}; + +struct cfgopt { + char *name; + int type; + long tm; + char *valstr; + vec3_t val, valrng; +}; + static int init_particle_attr(struct psys_particle_attributes *pattr); static void destroy_particle_attr(struct psys_particle_attributes *pattr); static char *stripspace(char *str); @@ -13,6 +29,7 @@ static unsigned int (*load_texture)(const char*, void*) = psys_gl_load_texture; static void (*unload_texture)(unsigned int, void*) = psys_gl_unload_texture; + void psys_texture_loader(unsigned int (*load)(const char*, void*), void (*unload)(unsigned int, void*), void *cls) { load_texture = load; @@ -132,27 +149,100 @@ psys_init_attr(attr); while(fgets(buf, sizeof buf, fp)) { - char *key, *valstr; + struct cfgopt opt; lineno++; - key = stripspace(buf); - if(key[0] == '#' || !key[0]) { - continue; // skip empty lines and comments + if(get_cfg_opt(buf, &opt) == -1) { + goto err; } - if(!(valstr = strchr(buf, '='))) { - fprintf(stderr "%s: invalid input: %s\n", __func__, line); - return -1; + if(strcmp(opt.name, "texture")) { + if(opt.type != OPT_STR) { + goto err; + } + /* XXX cont. */ } - *valstr++ = 0; - valstr = stripspace(valstr); + } +err: + fprintf(stderr, "Line %d: error parsing particle definition\n", lineno); + psys_destroy_attr(attr); + return -1; +} +/* strdup on the stack with alloca */ +#define strdup_stack(s) \ + do { \ + size_t len = strlen(s); \ + char *res = alloca(len + 1); \ + memcpy(res, s, len + 1); \ + } while(0) + +static int get_cfg_opt(const char *line, struct cfgopt *opt) +{ + char *buf; + float tmsec; + + line = stripspace(line); + if(line[0] == '#' || !line[0]) { + return 0; /* skip empty lines and comments */ } + if(!(opt->valstr = strchr(line, '='))) { + return -1; + } + *opt->valstr++ = 0; + opt->valstr = stripspace(opt->valstr); + + /* allocate a working buffer on the stack that could fit the current line */ + buf = alloca(strlen(line) + 1); + + if(sscanf(line, "%s(%fs)", buf, &tmsec) == 2) { + opt->tm = (long)(tmsec * 1000.0f); + opt->name = strdup_stack(buf); + } else if(sscanf(line, "%s(%ld)", buf, &opt->tm) == 2) { + opt->name = strdup_stack(buf); + } else { + opt->name = strdup_stack(buf); + opt->tm = 0; + } + + if(sscanf(opt->valstr, "[%f %f %f] ~ [%f %f %f]", &opt->val.x, &opt->val.y, &opt->val.z, + &opt->valrng.x, &opt->valrng.y, &opt->valrng.z) == 6) { + /* value is a vector range */ + opt->type = OPT_VEC_RANGE; + + } else if(sscanf(opt->valstr, "%f ~ %f", &opt->val.x, &opt->valrng.x) == 2) { + /* value is a number range */ + opt->type = OPT_NUM_RANGE; + opt->val.y = opt->val.z = opt->val.x; + opt->valrng.y = opt->valrng.z = opt->valrgn.x; + + } else if(sscanf(opt->valstr, "[%f %f %f]", &opt->val.x, &opt->val.y, &opt->val.z) == 3) { + /* value is a vector */ + opt->type = OPT_VEC; + opt->valrng.x = opt->valrng.y = opt->valrng.z = 0.0f; + + } else if(sscanf(opt->valstr, "%f", &opt->val.x) == 1) { + /* value is a number */ + opt->type = OPT_NUM; + opt->val.y = opt->val.z = opt->val.x; + opt->valrng.x = opt->valrng.y = opt->valrng.z = 0.0f; + + } else if(sscanf(opt->valstr, "\"%s\"", buf) == 1) { + /* just a string... strip the quotes */ + opt->type = OPT_STR; + opt->valstr = strdup_stack(buf); + } else { + /* fuck it ... */ + return -1; + } + + return 0; } + int psys_save_attr(struct psys_attributes *attr, const char *fname) { FILE *fp; diff -r 1b0db53d5b5b -r 4f36bbbcc82f src/pattr_parser.c --- a/src/pattr_parser.c Thu Sep 06 02:32:58 2012 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -#include "pattr_parser.h" - -struct cfg_node *psys_parse(const char *buf) -{ - -} diff -r 1b0db53d5b5b -r 4f36bbbcc82f src/pattr_parser.h --- a/src/pattr_parser.h Thu Sep 06 02:32:58 2012 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -#ifndef PATTR_PARSER_H_ -#define PATTR_PARSER_H_ - -struct cfg_value { - int nelem; - float v[4]; -}; - -struct cfg_node { - char *name, *valstr; - - long tm; - struct cfg_value val, range; - - struct cfg_node *next; -}; - -struct cfg_node *psys_parse(const char *buf); - - -#endif /* PATTR_PARSER_H_ */