It appears Solaris's cc is ignoring the signedness of bitfield types.
[xiph/unicode.git] / sushivision / objective.c
blob3b96b8db5b23252ccf59e4610195d30ad41eaa31
1 /*
3 * sushivision copyright (C) 2006-2007 Monty <monty@xiph.org>
5 * sushivision is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * sushivision is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with sushivision; see the file COPYING. If not, write to the
17 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include "internal.h"
28 int _sv_objectives=0;
29 sv_obj_t **_sv_objective_list=NULL;
30 pthread_key_t _sv_obj_key;
32 static char *objective_axismap[]={
33 "X","Y","Z"
36 #define map_axes ((int)sizeof(objective_axismap)/(int)sizeof(*objective_axismap))
38 int sv_obj_new(char *name,
39 void(*function)(double *,double *),
40 char *input_map,
41 char *output_map){
43 sv_obj_t *o = NULL;
44 int i,j;
45 int number;
46 _sv_token *decl = _sv_tokenize_declparam(name);
47 _sv_tokenlist *in = NULL;
48 _sv_tokenlist *out = NULL;
50 if(!decl){
51 fprintf(stderr,"sushivision: Unable to parse objective declaration \"%s\".\n",name);
52 goto err;
55 if(_sv_objectives == 0){
56 number=0;
57 _sv_objective_list = calloc (number+1,sizeof(*_sv_objective_list));
58 _sv_objectives=1;
59 }else{
60 for(number=0;number<_sv_objectives;number++)
61 if(!_sv_objective_list[number])break;
62 if(number==_sv_objectives){
63 _sv_objectives=number+1;
64 _sv_objective_list = realloc (_sv_objective_list,_sv_objectives * sizeof(*_sv_objective_list));
68 o = _sv_objective_list[number] = calloc(1, sizeof(**_sv_objective_list));
69 o->name = strdup(decl->name);
70 o->legend = strdup(decl->label);
71 o->number = number;
72 o->function = function;
74 /* parse and sanity check the maps */
75 in = _sv_tokenize_noparamlist(input_map);
76 out = _sv_tokenize_noparamlist(output_map);
78 /* input dimensions */
79 if(!in){
80 fprintf(stderr,"sushivision: Unable to parse objective \"%s\" dimenension list \"%s\".\n",
81 o->name,input_map);
82 goto err;
85 o->inputs = in->n;
86 o->input_dims = calloc(in->n,sizeof(*o->input_dims));
87 for(i=0;i<in->n;i++){
88 sv_dim_t *id = sv_dim(in->list[i]->name);
89 if(!id){
90 fprintf(stderr,"sushivision: Dimension \"%s\" does not exist in declaration of objective \"%s\".\n",
91 in->list[i]->name,o->name);
92 goto err;
94 o->input_dims[i] = id;
97 /* output axes */
98 o->outputs = out->n;
99 o->output_axes = malloc(map_axes * sizeof(*o->output_axes));
100 for(i=0;i<map_axes;i++)
101 o->output_axes[i]=-1;
103 for(i=0;i<out->n;i++){
104 char *s = out->list[i]->name;
105 if(!s || !strcasecmp(s,"*")){
106 // output unused by objective
107 // do nothing
108 }else{
109 for(j=0;j<map_axes;j++){
110 if(!strcasecmp(s,objective_axismap[j])){
112 if(o->output_axes[j] != -1){
113 fprintf(stderr,"sushivision: Objective \"%s\" declares multiple %s axis outputs.\n",
114 o->name,objective_axismap[j]);
115 goto err;
117 o->output_axes[j] = i;
120 if(j==map_axes){
121 fprintf(stderr,"sushivision: No such output axis \"%s\" in declaration of objective \"%s\"\n",
122 s,o->name);
127 pthread_setspecific(_sv_obj_key, (void *)o);
129 _sv_token_free(decl);
130 _sv_tokenlist_free(in);
131 _sv_tokenlist_free(out);
133 return 0;
135 err:
136 // XXXXX
138 return -EINVAL;
141 // XXXX need to recompute after
142 // XXXX need to add scale cloning to compute to make this safe in callbacks
143 int sv_obj_set_scale(sv_scale_t *scale){
144 sv_obj_t *o = _sv_obj(0);
146 if(o->scale)
147 sv_scale_free(o->scale); // always a deep copy we own
149 o->scale = (sv_scale_t *)sv_scale_copy(scale);
151 // redraw the slider
153 return 0;
156 // XXXX need to recompute after
157 // XXXX need to add scale cloning to compute to make this safe in callbacks
158 int sv_obj_make_scale(char *format){
159 sv_obj_t *o = _sv_obj(0);
160 sv_scale_t *scale;
161 int ret;
163 char *name=_sv_tokenize_escape(o->name);
164 char *label=_sv_tokenize_escape(o->legend);
165 char *arg=calloc(strlen(name)+strlen(label)+2,sizeof(*arg));
167 strcat(arg,name);
168 strcat(arg,":");
169 strcat(arg,label);
170 free(name);
171 free(label);
173 if(!o){
174 free(arg);
175 return -EINVAL;
177 scale = sv_scale_new(arg,format);
178 free(arg);
179 if(!scale)return errno;
181 o->scale = scale;
182 return ret;
185 sv_obj_t *_sv_obj(char *name){
186 int i;
188 if(name == NULL || name == 0 || !strcmp(name,"")){
189 return (sv_obj_t *)pthread_getspecific(_sv_obj_key);
192 for(i=0;i<_sv_objectives;i++){
193 sv_obj_t *o=_sv_objective_list[i];
194 if(o && o->name && !strcmp(name,o->name)){
195 pthread_setspecific(_sv_obj_key, (void *)o);
196 return o;
199 return NULL;
202 int sv_obj(char *name){
203 sv_obj_t *o = _sv_obj(name);
204 if(o)return 0;
205 return -EINVAL;