[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