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_ */