1 /*************************************************************************/
2 /*                                                                       */
3 /*                  Language Technologies Institute                      */
4 /*                     Carnegie Mellon University                        */
5 /*                        Copyright (c) 1999                             */
6 /*                        All Rights Reserved.                           */
7 /*                                                                       */
8 /*  Permission is hereby granted, free of charge, to use and distribute  */
9 /*  this software and its documentation without restriction, including   */
10 /*  without limitation the rights to use, copy, modify, merge, publish,  */
11 /*  distribute, sublicense, and/or sell copies of this work, and to      */
12 /*  permit persons to whom this work is furnished to do so, subject to   */
13 /*  the following conditions:                                            */
14 /*   1. The code must retain the above copyright notice, this list of    */
15 /*      conditions and the following disclaimer.                         */
16 /*   2. Any modifications must be clearly marked as such.                */
17 /*   3. Original authors' names are not deleted.                         */
18 /*   4. The authors' names are not used to endorse or promote products   */
19 /*      derived from this software without specific prior written        */
20 /*      permission.                                                      */
21 /*                                                                       */
22 /*  CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK         */
23 /*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      */
24 /*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
25 /*  SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE      */
26 /*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    */
27 /*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   */
28 /*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          */
29 /*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       */
30 /*  THIS SOFTWARE.                                                       */
31 /*                                                                       */
32 /*************************************************************************/
33 /*             Author:  Alan W Black (awb@cs.cmu.edu)                    */
34 /*               Date:  December 1999                                    */
35 /*************************************************************************/
36 /*                                                                       */
37 /*    Feature support                                                    */
38 /*                                                                       */
39 /*************************************************************************/
40 
41 #include "cst_error.h"
42 #include "cst_features.h"
43 
CST_VAL_REGISTER_TYPE(features,cst_features)44 CST_VAL_REGISTER_TYPE(features,cst_features)
45 
46 static cst_featvalpair *feat_find_featpair(const cst_features *f,
47 					   const char *name)
48 {
49     cst_featvalpair *n;
50 
51     if (f == NULL)
52 	return NULL;
53     else
54     {
55 	for (n=f->head; n; n=n->next)
56 	    if (cst_streq(name,n->name))
57 		return n;
58 	return NULL;
59     }
60 }
61 
new_features(void)62 cst_features *new_features(void)
63 {
64     cst_features *f;
65 
66     f = cst_alloc(cst_features,1);
67     f->head = NULL;
68     f->ctx = NULL;
69     return f;
70 }
71 
new_features_local(cst_alloc_context ctx)72 cst_features *new_features_local(cst_alloc_context ctx)
73 {
74     cst_features *f;
75 
76     f = (cst_features *)cst_local_alloc(ctx, sizeof(*f));
77     f->head = NULL;
78     f->ctx = ctx;
79     return f;
80 }
81 
delete_features(cst_features * f)82 void delete_features(cst_features *f)
83 {
84     cst_featvalpair *n, *np;
85 
86     if (f)
87     {
88 	for (n=f->head; n; n=np)
89 	{
90 	    np = n->next;
91 	    delete_val(n->val);
92 	    cst_local_free(f->ctx,n);
93 	}
94         delete_val(f->owned_strings);
95 	cst_local_free(f->ctx,f);
96     }
97 }
98 
feat_present(const cst_features * f,const char * name)99 int feat_present(const cst_features *f, const char *name)
100 {
101     if (feat_find_featpair(f,name) != NULL)
102         return 1;
103     else if (f && f->linked)
104         return feat_present(f->linked,name);
105     else
106         return 0;
107 }
108 
feat_length(const cst_features * f)109 int feat_length(const cst_features *f)
110 {
111     int i=0;
112     cst_featvalpair *p;
113     if (f)
114 	for (i=0,p=f->head; p; p=p->next)
115 	    i++;
116     return i;
117 }
118 
feat_remove(cst_features * f,const char * name)119 int feat_remove(cst_features *f, const char *name)
120 {
121     cst_featvalpair *n,*p,*np;
122 
123     if (f == NULL)
124 	return FALSE; /* didn't remove it */
125     else
126     {
127 	for (p=NULL,n=f->head; n; p=n,n=np)
128 	{
129 	    np = n->next;
130 	    if (cst_streq(name,n->name))
131 	    {
132 		if (p == 0)
133 		    f->head = np;
134 		else
135 		    p->next = np;
136 		delete_val(n->val);
137 		cst_local_free(f->ctx,n);
138 		return TRUE;
139 	    }
140 	}
141 	return FALSE;
142     }
143 }
144 
feat_int(const cst_features * f,const char * name)145 int feat_int(const cst_features *f, const char *name)
146 {
147     return val_int(feat_val(f,name));
148 }
149 
feat_float(const cst_features * f,const char * name)150 float feat_float(const cst_features *f, const char *name)
151 {
152     return val_float(feat_val(f,name));
153 }
154 
feat_string(const cst_features * f,const char * name)155 const char *feat_string(const cst_features *f, const char *name)
156 {
157     return val_string(feat_val(f,name));
158 }
159 
feat_val(const cst_features * f,const char * name)160 const cst_val *feat_val(const cst_features *f, const char *name)
161 {
162     cst_featvalpair *n;
163     n = feat_find_featpair(f,name);
164 
165     if (n == NULL)
166     {
167         if (f && f->linked)
168         {   /* Search the linked features too if there are any */
169             /* We assume the linked features haven't been deleted, and */
170             return feat_val(f->linked,name);
171         }
172         else
173             return NULL; /* its really not there at all */
174     }
175     else
176 	return n->val;
177 }
178 
get_param_int(const cst_features * f,const char * name,int def)179 int get_param_int(const cst_features *f, const char *name,int def)
180 {
181     const cst_val *v;
182 
183     v = feat_val(f,name);
184     if (v != NULL)
185         return val_int(v);
186     else
187 	return def;
188 }
189 
get_param_float(const cst_features * f,const char * name,float def)190 float get_param_float(const cst_features *f, const char *name, float def)
191 {
192     const cst_val *v;
193 
194     v = feat_val(f,name);
195     if (v != NULL)
196         return val_float(v);
197     else
198 	return def;
199 }
get_param_string(const cst_features * f,const char * name,const char * def)200 const char *get_param_string(const cst_features *f, const char *name, const char *def)
201 {
202     const cst_val *v;
203 
204     v = feat_val(f,name);
205     if (v != NULL)
206         return val_string(v);
207     else
208 	return def;
209 }
210 
get_param_val(const cst_features * f,const char * name,cst_val * def)211 const cst_val *get_param_val(const cst_features *f, const char *name, cst_val *def)
212 {
213     const cst_val *v;
214 
215     v = feat_val(f,name);
216     if (v != NULL)
217         return v;
218     else
219 	return def;
220 }
221 
feat_set_int(cst_features * f,const char * name,int v)222 void feat_set_int(cst_features *f, const char *name, int v)
223 {
224     feat_set(f,name,int_val(v));
225 }
226 
feat_set_float(cst_features * f,const char * name,float v)227 void feat_set_float(cst_features *f, const char *name, float v)
228 {
229     feat_set(f,name,float_val(v));
230 }
231 
feat_set_string(cst_features * f,const char * name,const char * v)232 void feat_set_string(cst_features *f, const char *name, const char *v)
233 {
234     feat_set(f,name,string_val(v));
235 }
236 
feat_set(cst_features * f,const char * name,const cst_val * val)237 void feat_set(cst_features *f, const char* name, const cst_val *val)
238 {
239     cst_featvalpair *n;
240     n = feat_find_featpair(f,name);
241 
242     if (val == NULL)
243     {
244 	cst_errmsg("cst_features: trying to set a NULL val for feature \"%s\"\n",
245 		   name);
246     }
247     else if (n == NULL)
248     {   /* first reference to this feature so create new fpair */
249 	cst_featvalpair *p;
250 	p = (cst_featvalpair *)cst_local_alloc(f->ctx, sizeof(*p));
251 	p->next = f->head;
252         p->name = name;
253 	p->val = val_inc_refcount(val);
254 	f->head = p;
255     }
256     else
257     {
258 	delete_val(n->val);
259 	n->val = val_inc_refcount(val);
260     }
261 }
262 
feat_copy_into(const cst_features * from,cst_features * to)263 int feat_copy_into(const cst_features *from,cst_features *to)
264 {
265     /* Copy all features in from into to */
266     cst_featvalpair *p;
267     int i;
268 
269     for (i=0,p=from->head; p; p=p->next,i++)
270 	feat_set(to,p->name,p->val);
271 
272     return i;
273 }
274 
feat_link_into(const cst_features * from,cst_features * to)275 int feat_link_into(const cst_features *from,cst_features *to)
276 {
277     /* Thus allows more global features to be linked, without a copy */
278     /* This is used to make things thread safe(r)                    */
279     to->linked = from;
280     return 1;
281 }
282 
feat_own_string(cst_features * f,const char * n)283 const char *feat_own_string(cst_features *f,const char *n)
284 {
285     f->owned_strings = cons_val(string_val(n),f->owned_strings);
286     return val_string(val_car(f->owned_strings));
287 }
288 
cst_feat_print(cst_file fd,const cst_features * f)289 int cst_feat_print(cst_file fd,const cst_features *f)
290 {
291     cst_featvalpair *p;
292 
293     for (p=f->head; p; p=p->next)
294     {
295 	cst_fprintf(fd, "%s ",p->name);
296 	val_print(fd,p->val);
297 	cst_fprintf(fd,"\n");
298     }
299 
300     return 0;
301 }
302