[xiph-commits] r13762 - trunk/sushivision
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Wed Sep 5 17:24:17 PDT 2007
Author: xiphmont
Date: 2007-09-05 17:24:17 -0700 (Wed, 05 Sep 2007)
New Revision: 13762
Modified:
trunk/sushivision/dimension.c
trunk/sushivision/example_fractal.c
trunk/sushivision/internal.h
trunk/sushivision/panel-1d.c
trunk/sushivision/panel-2d.c
trunk/sushivision/panel-xy.c
trunk/sushivision/panel.c
trunk/sushivision/scale.c
trunk/sushivision/sushivision.h
trunk/sushivision/tokens.c
Log:
Continued API rework; most tokenization code is done, needs to be fully bolted in.
Modified: trunk/sushivision/dimension.c
===================================================================
--- trunk/sushivision/dimension.c 2007-09-05 20:00:11 UTC (rev 13761)
+++ trunk/sushivision/dimension.c 2007-09-06 00:24:17 UTC (rev 13762)
@@ -674,10 +674,19 @@
unsigned flags){
sv_dim_t *d;
+ _sv_token *decl = _sv_tokenize_declparam(name);
+ if(!decl){
+ fprintf(stderr,"sushivision: Unable to parse dimension name \"%s\".\n",name);
+ errno = -EINVAL;
+ //XXXX leak
+ return NULL;
+ }
+
if(number<0){
fprintf(stderr,"Dimension number must be >= 0\n");
errno = -EINVAL;
+ //XXXX leak
return NULL;
}
@@ -685,6 +694,7 @@
if(_sv_dimension_list[number]!=NULL){
fprintf(stderr,"Dimension number %d already exists\n",number);
errno = -EINVAL;
+ //XXXleak
return NULL;
}
}else{
@@ -699,13 +709,15 @@
d = _sv_dimension_list[number] = calloc(1, sizeof(**_sv_dimension_list));
d->number = number;
- d->name = strdup(name);
+ d->name = strdup(decl->name);
+ d->legend = strdup(decl->label);
d->flags = flags;
d->type = SV_DIM_CONTINUOUS;
d->private = calloc(1, sizeof(*d->private));
pthread_setspecific(_sv_dim_key, (void *)d);
+ _sv_token_free(decl);
return d;
}
@@ -736,9 +748,22 @@
sv_dim_t *d = sv_dim(0);
sv_scale_t *scale;
int ret;
+ char *name=_sv_tokenize_escape(d->name);
+ char *label=_sv_tokenize_escape(d->legend);
+ char *arg=calloc(strlen(name)+strlen(label)+2,sizeof(*arg));
- if(!d) return -EINVAL;
- scale = sv_scale_new(d->name,format);
+ strcat(arg,name);
+ strcat(arg,":");
+ strcat(arg,label);
+ free(name);
+ free(label);
+
+ if(!d){
+ free(arg);
+ return -EINVAL;
+ }
+ scale = sv_scale_new(arg,format);
+ free(arg);
if(!scale)return errno;
d->scale = scale;
Modified: trunk/sushivision/example_fractal.c
===================================================================
--- trunk/sushivision/example_fractal.c 2007-09-05 20:00:11 UTC (rev 13761)
+++ trunk/sushivision/example_fractal.c 2007-09-06 00:24:17 UTC (rev 13762)
@@ -59,20 +59,20 @@
// "name:label(arg,arg,arg...)"
- sv_dim_t *d0 = sv_dim_new(0, "Re(c)", 0);
- sv_dim_make_scale("-2.25; -0.75; 0; 0.25; 0.75");
+ sv_dim_t *d0 = sv_dim_new(0, "rc:Re\\(c\\)", 0);
+ sv_dim_make_scale("-2.25, -0.75, 0, 0.25, 0.75");
- sv_dim_t *d1 = sv_dim_new(1, "Im(c)", 0);
- sv_dim_make_scale("-2;-1;0;1;2");
+ sv_dim_t *d1 = sv_dim_new(1, "ic:Im\\(c\\)", 0);
+ sv_dim_make_scale("-2,-1,0,1,2");
- sv_dim_t *d2 = sv_dim_new(2, "Re(z0)", 0);
- sv_dim_make_scale("-2.25; -1; 0; 1; 2.25");
+ sv_dim_t *d2 = sv_dim_new(2, "rz:Re\\(z0\\)", 0);
+ sv_dim_make_scale("-2.25, -1, 0, 1, 2.25");
- sv_dim_t *d3 = sv_dim_new(3, "Im(z0)", 0);
- sv_dim_make_scale("-2.25; -1; 0; 1; 2.25");
+ sv_dim_t *d3 = sv_dim_new(3, "iz:Im\\(z0\\)", 0);
+ sv_dim_make_scale("-2.25, -1, 0, 1, 2.25");
- sv_dim_t *d4 = sv_dim_new(4, "Max Iterations", 0);
- sv_dim_make_scale("100:one hundred; 1000:one thousand; 10000:ten thousand; 100000:one hundred thousand");
+ sv_dim_t *d4 = sv_dim_new(4, "it:Max Iterations", 0);
+ sv_dim_make_scale("100:one hundred, 1000:one thousand, 10000:ten thousand, 100000:one hundred thousand");
sv_dim_set_picklist();
sv_dim_set_value(100);
@@ -83,17 +83,17 @@
(sv_func_t *[]){f},
(int []){0},
"Y", 0);
- sv_obj_make_scale(o0, "0; .001; .01; .1; 1.0");
+ sv_obj_make_scale(o0, "0, .001, .01, .1, 1.0");
sv_obj_t *o1 = sv_obj_new(1,"inner",
(sv_func_t *[]){f},
(int []){1},
"Y", 0);
- sv_obj_make_scale(o1, "0; .001; .01; .1; 1.0");
+ sv_obj_make_scale(o1, "0, .001, .01, .1, 1.0");
sv_panel_new_2d(0,"Mandel/Julia Fractal",
(sv_obj_t *[]){o0,o1,NULL},
- (sv_dim_t *[]){d0,d1,d2,d3,d4,NULL},
+ "rc,ic,rz,iz,it",
0);
sv_go();
Modified: trunk/sushivision/internal.h
===================================================================
--- trunk/sushivision/internal.h 2007-09-05 20:00:11 UTC (rev 13761)
+++ trunk/sushivision/internal.h 2007-09-06 00:24:17 UTC (rev 13762)
@@ -30,12 +30,16 @@
#include "sushivision.h"
typedef struct {
+ char *s;
+ double v;
+} _sv_tokenval;
+
+typedef struct {
char *name;
char *label;
int n;
- char **options;
- double *values;
+ _sv_tokenval **values;
} _sv_token;
typedef struct {
@@ -43,10 +47,33 @@
_sv_token **list;
} _sv_tokenlist;
+// name string
+// labelname name[:string]
+// displayvalue number[:string]
+// flag string
+// parameter {flag|string=number}
+// parameterlist paramentry[, paramentry[...]]
+// valuelist displayvalue[, displayvalue[...]]
+// declparam label(parameterlist)
+// nameparam name(parameterlist)
+// namelist nameparam[, nameparam[...]]
+
+extern char *_sv_tokenize_string(char *in);
+extern _sv_tokenval *_sv_tokenize_number(char *in);
+extern _sv_token *_sv_tokenize_name(char *in);
+extern _sv_token *_sv_tokenize_labelname(char *in);
+extern _sv_tokenval *_sv_tokenize_displayvalue(char *in);
+extern _sv_tokenval *_sv_tokenize_flag(char *in);
+extern _sv_tokenval *_sv_tokenize_parameter(char *in);
+extern _sv_token *_sv_tokenize_parameterlist(char *in);
+extern _sv_token *_sv_tokenize_valuelist(char *in);
+extern _sv_token *_sv_tokenize_nameparam(char *in);
+extern _sv_token *_sv_tokenize_declparam(char *in);
+extern _sv_tokenlist *_sv_tokenize_namelist(char *in);
+extern void _sv_tokenval_free(_sv_tokenval *t);
extern void _sv_token_free(_sv_token *t);
extern void _sv_tokenlist_free(_sv_tokenlist *l);
-extern _sv_token *_sv_tokenize(char *in);
-extern _sv_tokenlist *_sv_tokenlistize(char *in);
+extern char *_sv_tokenize_escape(char *a);
// used to glue numeric settings to semantic labels for menus/save files
typedef struct _sv_propmap _sv_propmap_t;
@@ -182,7 +209,7 @@
extern sv_panel_t *_sv_panel_new(int number,
char *name,
sv_obj_t **objectives,
- sv_dim_t **dimensions,
+ char *dimensionlist,
unsigned flags);
extern void _sv_panel_realize(sv_panel_t *p);
extern void _sv_panel_dirty_map(sv_panel_t *p);
Modified: trunk/sushivision/panel-1d.c
===================================================================
--- trunk/sushivision/panel-1d.c 2007-09-05 20:00:11 UTC (rev 13761)
+++ trunk/sushivision/panel-1d.c 2007-09-06 00:24:17 UTC (rev 13762)
@@ -1422,10 +1422,10 @@
char *name,
sv_scale_t *scale,
sv_obj_t **objectives,
- sv_dim_t **dimensions,
+ char *dimensionlist,
unsigned flags){
- sv_panel_t *p = _sv_panel_new(number,name,objectives,dimensions,flags);
+ sv_panel_t *p = _sv_panel_new(number,name,objectives,dimensionlist,flags);
_sv_panel1d_t *p1;
if(!p)return p;
Modified: trunk/sushivision/panel-2d.c
===================================================================
--- trunk/sushivision/panel-2d.c 2007-09-05 20:00:11 UTC (rev 13761)
+++ trunk/sushivision/panel-2d.c 2007-09-06 00:24:17 UTC (rev 13762)
@@ -896,7 +896,7 @@
if( (d!=p->private->x_d && d!=p->private->y_d) ||
plot->cross_active){
snprintf(buffer,320,"%s = %+.*f",
- p->dimension_list[i].d->name,
+ p->dimension_list[i].d->legend,
depth,
p->dimension_list[i].d->val);
_sv_plot_legend_add(plot,buffer);
@@ -1428,7 +1428,7 @@
p->private->x_d->bracket[1],
pw,pw * p->private->oversample_n / p->private->oversample_d,
plot->scalespacing,
- p->private->x_d->name,
+ p->private->x_d->legend,
&sx,
&sx_v,
&sx_i);
@@ -1437,7 +1437,7 @@
p->private->y_d->bracket[0],
ph,ph * p->private->oversample_n / p->private->oversample_d,
plot->scalespacing,
- p->private->y_d->name,
+ p->private->y_d->legend,
&sy,
&sy_v,
&sy_i);
@@ -1767,7 +1767,7 @@
sv_dim_t *d = p->dimension_list[i].d;
/* label */
- GtkWidget *label = gtk_label_new(d->name);
+ GtkWidget *label = gtk_label_new(d->legend);
gtk_misc_set_alignment(GTK_MISC(label),1.,.5);
gtk_table_attach(GTK_TABLE(p2->dim_table),label,0,1,i,i+1,
GTK_FILL,0,5,0);
@@ -1928,11 +1928,11 @@
sv_panel_t *sv_panel_new_2d(int number,
char *name,
sv_obj_t **objectives,
- sv_dim_t **dimensions,
+ char *dimensionlist,
unsigned flags){
int i,j;
- sv_panel_t *p = _sv_panel_new(number,name,objectives,dimensions,flags);
+ sv_panel_t *p = _sv_panel_new(number,name,objectives,dimensionlist,flags);
if(!p)return NULL;
_sv_panel2d_t *p2 = calloc(1, sizeof(*p2));
Modified: trunk/sushivision/panel-xy.c
===================================================================
--- trunk/sushivision/panel-xy.c 2007-09-05 20:00:11 UTC (rev 13761)
+++ trunk/sushivision/panel-xy.c 2007-09-06 00:24:17 UTC (rev 13762)
@@ -1609,10 +1609,10 @@
sv_scale_t *xscale,
sv_scale_t *yscale,
sv_obj_t **objectives,
- sv_dim_t **dimensions,
+ char *dimensionlist,
unsigned flags){
- sv_panel_t *p = _sv_panel_new(number,name,objectives,dimensions,flags);
+ sv_panel_t *p = _sv_panel_new(number,name,objectives,dimensionlist,flags);
_sv_panelxy_t *xy;
if(!p)return NULL;
Modified: trunk/sushivision/panel.c
===================================================================
--- trunk/sushivision/panel.c 2007-09-05 20:00:11 UTC (rev 13761)
+++ trunk/sushivision/panel.c 2007-09-06 00:24:17 UTC (rev 13762)
@@ -803,11 +803,11 @@
sv_panel_t * _sv_panel_new(int number,
char *name,
sv_obj_t **objectives,
- char *dimensions,
+ char *dimensionlist,
unsigned flags){
sv_panel_t *p;
- char **dim_tokens;
+ _sv_tokenlist *dim_tokens;
int i;
if(number<0){
@@ -852,24 +852,26 @@
}
i=0;
- dim_tokens = _sv_tokenize(dimensions,';',1);
- while(dim_tokens && dim_tokens[i])i++;
- p->dimensions = i;
- p->dimension_list = malloc(i*sizeof(*p->dimension_list));
+ dim_tokens = _sv_tokenize_namelist(dimensionlist);
+ p->dimensions = dim_tokens->n;
+ p->dimension_list = malloc(p->dimensions*sizeof(*p->dimension_list));
for(i=0;i<p->dimensions;i++){
- sv_dim_t *d = sv_dim(dim_tokensi[i]);
+ char *name = dim_tokens->list[i]->name;
+ sv_dim_t *d = sv_dim(name);
if(!d){
fprintf(stderr,"Panel %d (\"%s\"): Dimension \"%s\" does not exist\n",
- number,p->name,dim_tokens[i]);
+ number,p->name,name);
errno = -EINVAL;
+ //XXX leak
return NULL;
}
- if(!dimensions[i]->scale){
- fprintf(stderr,"Panel %d (\"%s\"): Dimension number \"%s\" has a NULL scale\n",
- number,p->name,dimensions[i]->name);
+ if(!d->scale){
+ fprintf(stderr,"Panel %d (\"%s\"): Dimension \"%s\" has a NULL scale\n",
+ number,p->name,name);
errno = -EINVAL;
+ //XXX leak
return NULL;
}
Modified: trunk/sushivision/scale.c
===================================================================
--- trunk/sushivision/scale.c 2007-09-05 20:00:11 UTC (rev 13761)
+++ trunk/sushivision/scale.c 2007-09-06 00:24:17 UTC (rev 13762)
@@ -28,7 +28,7 @@
#include <limits.h>
#include <ctype.h>
#include "sushivision.h"
-#include "scale.h"
+#include "internal.h"
/* slider scales */
void sv_scale_free(sv_scale_t *in){
@@ -47,59 +47,34 @@
}
}
-sv_scale_t *sv_scale_new(char *arg){
+sv_scale_t *sv_scale_new(char *name, char *vals){
int i=0;
- _sv_tokenlist *t= _sv_tokenlistize(format);
+ _sv_token *decl= _sv_tokenize_declparam(name);
+ _sv_token *list= _sv_tokenize_valuelist(vals);
// sanity check the tokenization
- if(!t){
- fprintf(stderr,"sushivision: Unable to parse scale argument \"%s\".\n",arg);
+ if(!decl){
+ fprintf(stderr,"sushivision: Unable to parse scale argument \"%s\".\n",name);
return NULL;
}
+ if(!list){
+ fprintf(stderr,"sushivision: Unable to parse scale argument \"%s\".\n",vals);
+ return NULL;
+ }
- if(t->n != 1)
- fprintf(stderr,"sushivision: Ignoring excess arguments to scale.\n");
-
- if(
-
sv_scale_t *s = calloc(1, sizeof(*s));
- s->vals = count;
+ s->vals = list->n;
s->val_list = calloc(s->vals,sizeof(*s->val_list));
s->label_list = calloc(s->vals,sizeof(*s->label_list));
- arg=format;
- while(arg && *arg){
- char *buf = strdup(arg);
- char *pos = strchr(buf,';');
- while(pos && *(pos-1)=='\\')
- pos = strchr(pos+1,';');
- if(!pos){
- arg=NULL;
- }else{
- arg+=pos-buf+1;
- pos[0]=0;
- }
-
- // an argument is a number and potentially a colon followed by an auxiliary label.
- pos = strchr(buf,':');
- if(pos){
- // we have a colon (label)
- s->label_list[i] = strdup(trim(pos+1));
- *pos='\0';
- }else{
- // we have only a number
- s->label_list[i] = strdup(trim(buf));
- }
- s->val_list[i]=atof_portable(buf);
- free(buf);
-
- i++;
+ for(i=0;i<s->vals;i++){
+ s->label_list[i] = strdup(list->values[i]->s);
+ s->val_list[i] = list->values[i]->v;
}
- if(legend)
- s->legend=strdup(legend);
- else
- s->legend=strdup("");
+ s->legend=strdup(decl->label);
+ _sv_token_free(decl);
+ _sv_token_free(list);
return s;
}
Modified: trunk/sushivision/sushivision.h
===================================================================
--- trunk/sushivision/sushivision.h 2007-09-05 20:00:11 UTC (rev 13761)
+++ trunk/sushivision/sushivision.h 2007-09-06 00:24:17 UTC (rev 13762)
@@ -59,8 +59,8 @@
unsigned flags;
};
-sv_scale_t *sv_scale_new (char *legend,
- char *format);
+sv_scale_t *sv_scale_new (char *name,
+ char *values);
sv_scale_t *sv_scale_copy (sv_scale_t *s);
@@ -80,6 +80,7 @@
struct sv_dim{
int number;
char *name;
+ char *legend;
enum sv_dim_type type;
double bracket[2];
@@ -217,7 +218,7 @@
char *name,
sv_scale_t *y_scale,
sv_obj_t **objectives,
- sv_dim_t **dimensions,
+ char *dimensions,
unsigned flags);
sv_panel_t *sv_panel_new_xy (int number,
@@ -225,13 +226,13 @@
sv_scale_t *x_scale,
sv_scale_t *y_scale,
sv_obj_t **objectives,
- sv_dim_t **dimensions,
+ char *dimensions,
unsigned flags);
sv_panel_t *sv_panel_new_2d (int number,
char *name,
sv_obj_t **objectives,
- sv_dim_t **dimensions,
+ char *dimensions,
unsigned flags);
int sv_panel_callback_recompute (sv_panel_t *p,
Modified: trunk/sushivision/tokens.c
===================================================================
--- trunk/sushivision/tokens.c 2007-09-05 20:00:11 UTC (rev 13761)
+++ trunk/sushivision/tokens.c 2007-09-06 00:24:17 UTC (rev 13762)
@@ -29,21 +29,30 @@
#include <math.h>
#include "internal.h"
+// not a true recursive parser as there's no arbitrary nesting.
+
+void _sv_tokenval_free(_sv_tokenval *v){
+ if(v){
+ if(v->s)free(v->s);
+ free(v);
+ }
+}
+
void _sv_token_free(_sv_token *t){
if(t){
if(t->name)free(t->name);
if(t->label)free(t->label);
- if(t->options){
+ if(t->values){
int i;
for(i=0;i<t->n;i++)
- if(t->options[i])free(t->options[i]);
- free(t->options);
+ if(t->values[i])_sv_tokenval_free(t->values[i]);
+ free(t->values);
}
- if(t->values)free(t->values);
free(t);
}
}
+
void _sv_tokenlist_free(_sv_tokenlist *l){
if(l){
if(l->list){
@@ -129,14 +138,18 @@
}
static char *trim(char *in){
- char *end;
+ char *head=in;
+ char *tail=in;
if(!in)return NULL;
- while(*in && isspace(*in))in++;
- end=in;
- while(*end)end++;
- while(end>in && (*end==0 || isspace(*end)))end--;
- if(*end)end[1]='\0';
+ while(*head && isspace(*head))head++;
+ while(*head){
+ *tail = *head;
+ tail++;
+ head++;
+ }
+ while(tail>in && isspace(*(tail-1)))tail--;
+ *tail=0;
return in;
}
@@ -165,6 +178,45 @@
return a;
}
+char *_sv_tokenize_escape(char *a){
+ char *head=a;
+ char *tail;
+ char *ret;
+ int count=0;
+
+ while(head && *head){
+ if(*head==':' ||
+ *head==',' ||
+ *head=='(' ||
+ *head==')' ||
+ isspace(*head) ||
+ *head=='\\')
+ count++;
+ count++;
+ head++;
+ }
+
+ head=a;
+ ret=tail=calloc(count+1,sizeof(*tail));
+
+ while(head && *head){
+ if(*head==':' ||
+ *head==',' ||
+ *head=='(' ||
+ *head==')' ||
+ isspace(*head) ||
+ *head=='\\'){
+ *tail='\\';
+ tail++;
+ }
+ *tail=*head;
+ tail++;
+ head++;
+ }
+
+ return ret;
+}
+
// split at unescaped, unenclosed seperator
// only parens enclose in our syntax
static char *split(char *a, char sep){
@@ -277,84 +329,170 @@
return NULL;
}
-// name:label(flag,param=val)
-// name:label(val:label, val:label...)
-_sv_token *_sv_tokenize(char *in){
+// a string is any C string of characters not containing unescaped
+// parens, commas, colons. Preceeding and trailing spaces are
+// stripped (escaped spaces are never stripped). Thus, parsing a
+// string consists only of stripping spaces and checking for illegal
+// characters.
+char *_sv_tokenize_string(char *in){
if(!in)return NULL;
char *a = strdup(in);
-
- // single arg; ignore anything following a level 0 comma
+ char *ret = NULL;
+
+ // ignore anything following a comma
if(split(a,','))
+ fprintf(stderr,"sushivision: ignoring trailing garbage \"%s\".\n",a);
+
+ // ignore anything following a colon
+ if(split(a,':'))
fprintf(stderr,"sushivision: ignoring trailing garbage after \"%s\".\n",a);
+
+ // complain about unescaped parens
+ if(unwrap(a))
+ fprintf(stderr,"sushivision: ignoring garbage after \"%s\".\n",a);
+
+ if(*a=='\0')goto done;
+
+ ret = strdup(trim(unescape(a)));
- // split name/label/args
- char *label=split(a,':');
- if(!label)label=a;
- char *p=unwrap(label);
+ done:
+ free(a);
+ return ret;
+}
+// a number is a standard printf format floating point number string
+// representation. It may not contain any characters (aside from
+// trailing/preceeding spaces) that are not part of the number
+// representation.
+_sv_tokenval *_sv_tokenize_number(char *in){
+ if(!in)return NULL;
+ char *a = strdup(in);
+ _sv_tokenval *ret=NULL;
+
+ a = trim(unescape(a));
if(*a=='\0')goto done;
- _sv_token *ret=calloc(1,sizeof(*ret));
- ret->name = strdup(trim(unescape(a)));
- ret->label = strdup(trim(unescape(label)));
+ ret=calloc(1,sizeof(*ret));
+ ret->s = strdup(a);
+ ret->v = atof_portable(a);
- if(p){
- int i;
- ret->n = splitcount(p,',');
- ret->options = calloc(ret->n,sizeof(*ret->options));
- ret->values = calloc(ret->n,sizeof(*ret->values));
-
- for(i=0;i<ret->n;i++){
- char *next = split(p,',');
- if(p){
- if(*p){
- // may have param=val or val:label syntax
- if(splitcount(p,':')>1){
-
- if(splitcount(p,'=')>1){
- fprintf(stderr,"sushivision: parameter \"%s\" contains both \":\" and \"=\"; \"=\" ignored.\n",p);
- }
- char *label = split(p,':');
- ret->options[i]=strdup(trim(unescape(label)));
- ret->values[i]=atof_portable(trim(unescape(p)));
-
- }else if(splitcount(p,'=')>1){
-
- char *val = split(p,'=');
- ret->options[i]=strdup(trim(unescape(p)));
- ret->values[i]=atof_portable(trim(unescape(val)));
-
- }else{
- ret->options[i]=strdup(trim(unescape(p)));
- ret->values[i]=atof_portable(trim(unescape(ret->options[i])));
- }
- }else{
- ret->values[i]=NAN;
- }
- }
- p=next;
- }
+ done:
+
+ free(a);
+ return ret;
+}
+
+_sv_token *_sv_tokenize_name(char *in){
+ _sv_token *ret = NULL;
+ char *s = _sv_tokenize_string(in);
+ if(!s)return NULL;
+
+ ret=calloc(1,sizeof(*ret));
+ ret->name = s;
+ return ret;
+}
+
+_sv_token *_sv_tokenize_labelname(char *in){
+ if(!in)return NULL;
+ char *a = strdup(in);
+ _sv_token *ret = NULL;
+
+ // split name/label
+ char *l=split(a,':');
+ ret = _sv_tokenize_name(a);
+ if(!ret)goto done;
+
+ if(!l){
+ ret->label = strdup(ret->name);
+ }else{
+ char *label = _sv_tokenize_string(l);
+ if(!label)
+ ret->label = strdup("");
+ else
+ ret->label = label;
}
+
done:
free(a);
return ret;
}
-_sv_tokenlist *_sv_tokenlistize(char *in){
+_sv_tokenval *_sv_tokenize_displayvalue(char *in){
if(!in)return NULL;
+ char *a = strdup(in);
+ _sv_tokenval *ret = NULL;
+ // split value/label
+ char *l=split(a,':');
+ ret = _sv_tokenize_number(a);
+ if(!ret)goto done;
+
+ if(l){
+ char *label = _sv_tokenize_string(l);
+ if(ret->s) free(ret->s);
+ if(!label)
+ ret->s = strdup("");
+ else
+ ret->s = label;
+ }
+
+ done:
+ free(a);
+ return ret;
+}
+
+_sv_tokenval *_sv_tokenize_flag(char *in){
+ _sv_tokenval *ret = NULL;
+ char *s = _sv_tokenize_string(in);
+ if(!s)return NULL;
+
+ ret=calloc(1,sizeof(*ret));
+ ret->s = s;
+ ret->v = NAN;
+ return ret;
+}
+
+_sv_tokenval *_sv_tokenize_parameter(char *in){
+
+ if(!in)return NULL;
+ char *a = strdup(in);
+ _sv_tokenval *ret = NULL;
+
+ // split value/label
+ char *l=split(a,'=');
+ if(!l){
+ ret = _sv_tokenize_flag(a);
+ }else{
+ ret = _sv_tokenize_number(l);
+ if(ret){
+ char *label = _sv_tokenize_string(a);
+ if(ret->s) free(ret->s);
+ if(!label)
+ ret->s = strdup("");
+ else
+ ret->s = label;
+ }
+ }
+
+ free(a);
+ return ret;
+}
+
+_sv_token *_sv_tokenize_parameterlist(char *in){
+ if(!in)return NULL;
+
char *l=strdup(in);
in=l;
int i,n = splitcount(l,',');
- _sv_tokenlist *ret = calloc(1,sizeof(*ret));
+ _sv_token *ret = calloc(1,sizeof(*ret));
ret->n = n;
- ret->list = calloc(n,sizeof(*ret->list));
+ ret->values = calloc(n,sizeof(*ret->values));
for(i=0;i<n;i++){
char *next = split(l,',');
- ret->list[i] = _sv_tokenize(l);
+ ret->values[i] = _sv_tokenize_parameter(l);
l=next;
}
free(in);
@@ -362,48 +500,113 @@
return ret;
}
-#if 0
+_sv_token *_sv_tokenize_valuelist(char *in){
+ if(!in)return NULL;
-int main(int argc, char **argv){
- int i;
- for(i=1;i<argc;i++){
- _sv_tokenlist *ret=_sv_tokenlistize(argv[i]);
- fprintf(stderr,"parsing arglist %d:\n\n",i);
- if(!ret)
- fprintf(stderr,"NULL");
- else{
- int j;
- fprintf(stderr,"arguments: %d",ret->n);
- for(j=0;j<ret->n;j++){
- fprintf(stderr,"\n\tname=%s, label=%s ",
- ret->list[j]->name,
- ret->list[j]->label);
- if(ret->list[j]->n){
- int k;
- fprintf(stderr,"(");
- for(k=0;k<ret->list[j]->n;k++){
- if(k>0)
- fprintf(stderr,", ");
- if(ret->list[j]->options[k]){
- if(*ret->list[j]->options[k]){
- fprintf(stderr,"%s",ret->list[j]->options[k]);
- }else{
- fprintf(stderr,"\"\"");
- }
- }else{
- fprintf(stderr,"NULL");
- }
- fprintf(stderr,"=%g",ret->list[j]->values[k]);
- }
- fprintf(stderr,")");
- }
- }
+ char *l=strdup(in);
+ in=l;
+
+ int i,n = splitcount(l,',');
+ _sv_token *ret = calloc(1,sizeof(*ret));
+
+ ret->n = n;
+ ret->values = calloc(n,sizeof(*ret->values));
+
+ for(i=0;i<n;i++){
+ char *next = split(l,',');
+ ret->values[i] = _sv_tokenize_displayvalue(l);
+ l=next;
+ }
+ free(in);
+
+ return ret;
+}
+
+_sv_token *_sv_tokenize_nameparam(char *in){
+ _sv_token *ret = NULL;
+ char *a=strdup(in);
+ char *p;
+ if(!a)return NULL;
+
+ // single arg; ignore anything following a level 0 comma
+ if(split(a,','))
+ fprintf(stderr,"sushivision: ignoring trailing garbage after \"%s\".\n",a);
+
+ // split name/args
+ p=unwrap(a);
+
+ if(*a=='\0')goto done;
+ ret = _sv_tokenize_name(a);
+
+ if(p){
+ _sv_token *l = _sv_tokenize_parameterlist(p);
+ if(l){
+ ret->n = l->n;
+ ret->values = l->values;
+
+ l->n = 0;
+ l->values = 0;
+ _sv_token_free(l);
}
- fprintf(stderr,"\n\n");
- _sv_tokenlist_free(ret);
}
- return 0;
+ done:
+ free(a);
+ return ret;
}
-#endif
+_sv_token *_sv_tokenize_declparam(char *in){
+ _sv_token *ret = NULL;
+ char *a=strdup(in);
+ char *p;
+ if(!a)return NULL;
+
+ // single arg; ignore anything following a level 0 comma
+ if(split(a,','))
+ fprintf(stderr,"sushivision: ignoring trailing garbage after \"%s\".\n",a);
+
+ // split name/args
+ p=unwrap(a);
+
+ if(*a=='\0')goto done;
+ ret = _sv_tokenize_labelname(a);
+
+ if(p){
+ _sv_token *l = _sv_tokenize_parameterlist(p);
+ if(l){
+ ret->n = l->n;
+ ret->values = l->values;
+
+ l->n = 0;
+ l->values = 0;
+ _sv_token_free(l);
+ }
+ }
+
+ done:
+ free(a);
+ return ret;
+}
+
+_sv_tokenlist *_sv_tokenize_namelist(char *in){
+ if(!in)return NULL;
+
+ char *l=strdup(in);
+ in=l;
+
+ int i,n = splitcount(l,',');
+ _sv_tokenlist *ret = calloc(1,sizeof(*ret));
+
+ ret->n = n;
+ ret->list = calloc(n,sizeof(*ret->list));
+
+ for(i=0;i<n;i++){
+ char *next = split(l,',');
+ ret->list[i] = _sv_tokenize_nameparam(l);
+ l=next;
+ }
+ free(in);
+
+ return ret;
+}
+
More information about the commits
mailing list