libpsys
changeset 14:4f36bbbcc82f
really started writting the parser... god I hate ad-hoc parsing...
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Mon, 10 Sep 2012 05:58:03 +0300 |
parents | 1b0db53d5b5b |
children | 5678915dc2c7 |
files | src/pattr.c src/pattr_parser.c src/pattr_parser.h |
diffstat | 3 files changed, 99 insertions(+), 36 deletions(-) [+] |
line diff
1.1 --- a/src/pattr.c Thu Sep 06 02:32:58 2012 +0300 1.2 +++ b/src/pattr.c Mon Sep 10 05:58:03 2012 +0300 1.3 @@ -5,6 +5,22 @@ 1.4 #include "pattr.h" 1.5 #include "psys_gl.h" 1.6 1.7 +enum { 1.8 + OPT_STR, 1.9 + OPT_NUM, 1.10 + OPT_NUM_RANGE, 1.11 + OPT_VEC, 1.12 + OPT_VEC_RANGE 1.13 +}; 1.14 + 1.15 +struct cfgopt { 1.16 + char *name; 1.17 + int type; 1.18 + long tm; 1.19 + char *valstr; 1.20 + vec3_t val, valrng; 1.21 +}; 1.22 + 1.23 static int init_particle_attr(struct psys_particle_attributes *pattr); 1.24 static void destroy_particle_attr(struct psys_particle_attributes *pattr); 1.25 static char *stripspace(char *str); 1.26 @@ -13,6 +29,7 @@ 1.27 static unsigned int (*load_texture)(const char*, void*) = psys_gl_load_texture; 1.28 static void (*unload_texture)(unsigned int, void*) = psys_gl_unload_texture; 1.29 1.30 + 1.31 void psys_texture_loader(unsigned int (*load)(const char*, void*), void (*unload)(unsigned int, void*), void *cls) 1.32 { 1.33 load_texture = load; 1.34 @@ -132,27 +149,100 @@ 1.35 psys_init_attr(attr); 1.36 1.37 while(fgets(buf, sizeof buf, fp)) { 1.38 - char *key, *valstr; 1.39 + struct cfgopt opt; 1.40 1.41 lineno++; 1.42 1.43 - key = stripspace(buf); 1.44 - if(key[0] == '#' || !key[0]) { 1.45 - continue; // skip empty lines and comments 1.46 + if(get_cfg_opt(buf, &opt) == -1) { 1.47 + goto err; 1.48 } 1.49 1.50 - if(!(valstr = strchr(buf, '='))) { 1.51 - fprintf(stderr "%s: invalid input: %s\n", __func__, line); 1.52 - return -1; 1.53 + if(strcmp(opt.name, "texture")) { 1.54 + if(opt.type != OPT_STR) { 1.55 + goto err; 1.56 + } 1.57 + /* XXX cont. */ 1.58 } 1.59 - *valstr++ = 0; 1.60 - valstr = stripspace(valstr); 1.61 + } 1.62 1.63 +err: 1.64 + fprintf(stderr, "Line %d: error parsing particle definition\n", lineno); 1.65 + psys_destroy_attr(attr); 1.66 + return -1; 1.67 +} 1.68 1.69 +/* strdup on the stack with alloca */ 1.70 +#define strdup_stack(s) \ 1.71 + do { \ 1.72 + size_t len = strlen(s); \ 1.73 + char *res = alloca(len + 1); \ 1.74 + memcpy(res, s, len + 1); \ 1.75 + } while(0) 1.76 + 1.77 +static int get_cfg_opt(const char *line, struct cfgopt *opt) 1.78 +{ 1.79 + char *buf; 1.80 + float tmsec; 1.81 + 1.82 + line = stripspace(line); 1.83 + if(line[0] == '#' || !line[0]) { 1.84 + return 0; /* skip empty lines and comments */ 1.85 } 1.86 + if(!(opt->valstr = strchr(line, '='))) { 1.87 + return -1; 1.88 + } 1.89 + *opt->valstr++ = 0; 1.90 + opt->valstr = stripspace(opt->valstr); 1.91 + 1.92 + /* allocate a working buffer on the stack that could fit the current line */ 1.93 + buf = alloca(strlen(line) + 1); 1.94 + 1.95 + if(sscanf(line, "%s(%fs)", buf, &tmsec) == 2) { 1.96 + opt->tm = (long)(tmsec * 1000.0f); 1.97 + opt->name = strdup_stack(buf); 1.98 + } else if(sscanf(line, "%s(%ld)", buf, &opt->tm) == 2) { 1.99 + opt->name = strdup_stack(buf); 1.100 + } else { 1.101 + opt->name = strdup_stack(buf); 1.102 + opt->tm = 0; 1.103 + } 1.104 + 1.105 + if(sscanf(opt->valstr, "[%f %f %f] ~ [%f %f %f]", &opt->val.x, &opt->val.y, &opt->val.z, 1.106 + &opt->valrng.x, &opt->valrng.y, &opt->valrng.z) == 6) { 1.107 + /* value is a vector range */ 1.108 + opt->type = OPT_VEC_RANGE; 1.109 + 1.110 + } else if(sscanf(opt->valstr, "%f ~ %f", &opt->val.x, &opt->valrng.x) == 2) { 1.111 + /* value is a number range */ 1.112 + opt->type = OPT_NUM_RANGE; 1.113 + opt->val.y = opt->val.z = opt->val.x; 1.114 + opt->valrng.y = opt->valrng.z = opt->valrgn.x; 1.115 + 1.116 + } else if(sscanf(opt->valstr, "[%f %f %f]", &opt->val.x, &opt->val.y, &opt->val.z) == 3) { 1.117 + /* value is a vector */ 1.118 + opt->type = OPT_VEC; 1.119 + opt->valrng.x = opt->valrng.y = opt->valrng.z = 0.0f; 1.120 + 1.121 + } else if(sscanf(opt->valstr, "%f", &opt->val.x) == 1) { 1.122 + /* value is a number */ 1.123 + opt->type = OPT_NUM; 1.124 + opt->val.y = opt->val.z = opt->val.x; 1.125 + opt->valrng.x = opt->valrng.y = opt->valrng.z = 0.0f; 1.126 + 1.127 + } else if(sscanf(opt->valstr, "\"%s\"", buf) == 1) { 1.128 + /* just a string... strip the quotes */ 1.129 + opt->type = OPT_STR; 1.130 + opt->valstr = strdup_stack(buf); 1.131 + } else { 1.132 + /* fuck it ... */ 1.133 + return -1; 1.134 + } 1.135 + 1.136 + return 0; 1.137 } 1.138 1.139 1.140 + 1.141 int psys_save_attr(struct psys_attributes *attr, const char *fname) 1.142 { 1.143 FILE *fp;
2.1 --- a/src/pattr_parser.c Thu Sep 06 02:32:58 2012 +0300 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,6 +0,0 @@ 2.4 -#include "pattr_parser.h" 2.5 - 2.6 -struct cfg_node *psys_parse(const char *buf) 2.7 -{ 2.8 - 2.9 -}
3.1 --- a/src/pattr_parser.h Thu Sep 06 02:32:58 2012 +0300 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,21 +0,0 @@ 3.4 -#ifndef PATTR_PARSER_H_ 3.5 -#define PATTR_PARSER_H_ 3.6 - 3.7 -struct cfg_value { 3.8 - int nelem; 3.9 - float v[4]; 3.10 -}; 3.11 - 3.12 -struct cfg_node { 3.13 - char *name, *valstr; 3.14 - 3.15 - long tm; 3.16 - struct cfg_value val, range; 3.17 - 3.18 - struct cfg_node *next; 3.19 -}; 3.20 - 3.21 -struct cfg_node *psys_parse(const char *buf); 3.22 - 3.23 - 3.24 -#endif /* PATTR_PARSER_H_ */