Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/openal-0.0.8/src/al_rcvar.c @ 17

Last change on this file since 17 was 17, checked in by landauf, 16 years ago

added openal

File size: 9.0 KB
Line 
1/* -*- mode: C; tab-width:8; c-basic-offset:8 -*-
2 * vi:set ts=8:
3 *
4 * al_rcvar.c
5 *
6 * Stuff related to the rcvar configuration interface
7 *
8 */
9#include "al_siteconfig.h"
10
11#include <AL/al.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15
16#include "al_config.h"
17#include "al_debug.h"
18#include "al_rcvar.h"
19#include "al_rctree.h"
20
21/*
22 * print_prim( Rcvar obj )
23 *
24 * Prints obj.
25 */
26static void print_prim( Rcvar obj );
27
28/*
29 * rc_lookup( const char *name )
30 *
31 * Returns the binding for the symbol named by name, if it exists, or NULL if
32 * it doesn't.
33 */
34Rcvar rc_lookup( const char *name ) {
35        return _alGlobalBinding( name );
36}
37
38/*
39 * rc_type( Rcvar sym )
40 *
41 * Returns the type of sym.
42 */
43ALRcEnum rc_type( Rcvar symp ) {
44        AL_rctree *sym = (AL_rctree *) symp;
45
46        if(sym == NULL) {
47                return ALRC_INVALID;
48        }
49
50        return sym->type;
51}
52
53/*
54 * rc_car( Rcvar sym )
55 *
56 * Returns the car portion of sym.  If sym is not a cons cell, returns NULL.
57 */
58Rcvar rc_car(Rcvar symp) {
59        return alrc_car( symp );
60}
61
62/*
63 * rc_cdr( Rcvar sym )
64 *
65 * Returns the cdr portion of sym.  If sym is not a cons cell, returns NULL.
66 */
67Rcvar rc_cdr(Rcvar symp) {
68        return alrc_cdr( symp );
69}
70
71/*
72 * If sym has type ALRC_STRING, this call populates retstr ( up to len bytes )
73 * with the value of the string.
74 */
75Rcvar rc_tostr0( Rcvar symp, char *retstr, size_t len ) {
76        AL_rctree *sym = (AL_rctree *) symp;
77        static AL_rctree retval;
78
79        if(sym == NULL) {
80                return NULL;
81        }
82
83        if(rc_type(sym) != ALRC_STRING) {
84                _alDebug(ALD_CONFIG, __FILE__, __LINE__,
85                      "Not a string");
86
87                return NULL;
88        }
89
90        if(len > sym->data.str.len) {
91                len = sym->data.str.len;
92        }
93
94        memcpy(retstr, sym->data.str.c_str, len);
95        retstr[len] = '\0';
96
97        retval = scmtrue;
98
99        return &retval;
100}
101
102/*
103 * If sym has type ALRC_SYMBOL, this call populates retstr ( up to len bytes )
104 * with the name of the symbol.
105 */
106Rcvar rc_symtostr0( Rcvar symp, char *retstr, size_t len ) {
107        AL_rctree *sym = (AL_rctree *) symp;
108        static AL_rctree retval;
109
110        if(sym == NULL) {
111                return NULL;
112        }
113
114        if(rc_type(sym) != ALRC_SYMBOL) {
115                _alDebug(ALD_CONFIG, __FILE__, __LINE__,
116                      "Not a string");
117
118                return NULL;
119        }
120
121        if(len > sym->data.str.len) {
122                len = sym->data.str.len;
123        }
124
125        memcpy(retstr, sym->data.str.c_str, len);
126        retstr[len] = '\0';
127
128        retval = scmtrue;
129
130        return &retval;
131}
132
133/*
134 * rc_tobool( Rcvar sym )
135 *
136 * Returns AL_TRUE if sym is a boolean type and equal to #t, AL_FALSE
137 * otherwise.
138 */
139ALboolean rc_tobool(Rcvar symp) {
140        AL_rctree *sym = (AL_rctree *) symp;
141
142        if(sym == NULL) {
143                return AL_FALSE;
144        }
145
146        if(sym->type != ALRC_BOOL) {
147                return AL_FALSE;
148        }
149
150        return sym->data.b;
151}
152
153/*
154 * rc_eval( const char *str )
155 *
156 * Evaluates str, returning result.
157 */
158Rcvar rc_eval( const char *str ) {
159        return (Rcvar) _alEvalStr( str );
160}
161
162/*
163 * rc_define( const char *symname, Rcvar val );
164 *
165 * Creates a binding between symname and the evaluation of val in the
166 * global scope, returning val.
167 */
168Rcvar rc_define( const char *symname, Rcvar value ) {
169        return _alDefine( symname, (AL_rctree *) value );
170}
171
172/*
173 * rc_typestr( ALRcEnum type )
174 *
175 * Returns a const char *representation of type.
176 */
177const char *rc_typestr( ALRcEnum type ) {
178        switch( type ) {
179                case ALRC_INVALID:
180                        return "ALRC_INVALID";
181                case ALRC_PRIMITIVE:
182                        return "ALRC_PRIMITIVE";
183                case ALRC_CONSCELL:
184                        return "ALRC_CONSCELL";
185                case ALRC_SYMBOL:
186                        return "ALRC_SYMBOL";
187                case ALRC_INTEGER:
188                        return "ALRC_INTEGER";
189                case ALRC_FLOAT:
190                        return "ALRC_FLOAT";
191                case ALRC_STRING:
192                        return "ALRC_STRING";
193                case ALRC_BOOL:
194                        return "ALRC_BOOL";
195                default:
196                        break;
197        }
198
199        return NULL;
200}
201
202/*
203 * rc_member( Rcvar ls, Rcvar sym )
204 *
205 * Returns a list with the first conscell to have a matching car with sym as
206 * its head, NULL otherwise.
207 */
208Rcvar rc_member( Rcvar ls, Rcvar symp ) {
209        if( rc_type(symp) != ALRC_CONSCELL ) {
210                return NULL;
211        }
212
213        if( rc_equal( rc_car( ls ), symp ) ) {
214                return ls;
215        }
216
217        return rc_member( rc_cdr(ls), symp );
218}
219
220/*
221 * rc_equal( Rcvar r1, Rcvar r2 )
222 *
223 * Returns AL_TRUE if r1 and r2 and equivilant, AL_FALSE otherwise.
224 */
225ALboolean rc_equal( Rcvar r1, Rcvar r2 ) {
226        if( rc_type(r1) != rc_type(r2) ) {
227                return AL_FALSE;
228        }
229
230        switch( rc_type(r1) ) {
231                case ALRC_INVALID:
232                        return AL_FALSE;
233                case ALRC_PRIMITIVE:
234                        return rc_toprim(r1) == rc_toprim(r2);
235                case ALRC_INTEGER:
236                        return rc_toint(r1) == rc_toint(r2);
237                case ALRC_FLOAT:
238                        return rc_tofloat(r1) == rc_tofloat(r2);
239                case ALRC_BOOL:
240                        return rc_tobool(r1) == rc_tobool(r2);
241                case ALRC_SYMBOL:
242                case ALRC_STRING:
243                        return rc_strequal(r1, r2);
244                case ALRC_CONSCELL:
245                        return rc_equal( rc_car(r1), rc_car(r2) ) &&
246                               rc_equal( rc_cdr(r1), rc_cdr(r2) );
247                default:
248                        break;
249        }
250
251        return AL_FALSE;
252}
253
254/*
255 * rc_toprim
256 *
257 * Returns an alrc from sym, or NULL if sym's type is not ALRC_PRIMITIVE.
258 */
259alrc_prim rc_toprim( Rcvar sym ) {
260        AL_rctree *r = sym;
261
262        if( rc_type(sym) != ALRC_PRIMITIVE ) {
263                assert(0);
264
265                return NULL;
266        }
267
268        return r->data.proc;
269}
270
271/*
272 * rc_toint( Rcvar sym )
273 *
274 * If sym is a numerical type, returns the integer value of sym.  Otherwise,
275 * returns 0.
276 */
277ALint rc_toint( Rcvar sym ) {
278        AL_rctree *r = sym;
279
280        switch( rc_type( sym ) ) {
281                case ALRC_INTEGER:
282                        return r->data.i;
283                case ALRC_FLOAT:
284                        return (ALint) r->data.f;
285                default:
286                        return 0;
287        }
288}
289
290/*
291 * rc_tofloat ( Rcvar sym )
292 *
293 * If sym is a numerical type, returns the float value of sym.  Otherwise,
294 * returns 0.0f.
295 */
296ALfloat rc_tofloat( Rcvar sym ) {
297        AL_rctree *r = sym;
298
299        if( rc_type(sym) == ALRC_INTEGER ) {
300                return rc_toint( sym );
301        }
302
303        if( rc_type( sym ) != ALRC_FLOAT ) {
304                return 0.0f;
305        }
306
307        return r->data.f;
308}
309
310/*
311 * rc_strequal( Rcvar d1, Rcvar d2 );
312 *
313 * If d1 and d2 both have type AL_STRING, returns AL_TRUE if there are
314 * equivilant.  Returns AL_FALSE otherwise.
315 */
316ALboolean rc_strequal( Rcvar d1, Rcvar d2 ) {
317        static char str1[65], str2[65];
318
319        switch( rc_type( d1 ) ) {
320                case ALRC_SYMBOL:
321                        rc_symtostr0( d1, str1, 65 );
322                        break;
323                case ALRC_STRING:
324                        rc_tostr0( d1, str1, 65 );
325                        break;
326                default:
327                        return AL_FALSE;
328        }
329
330        switch( rc_type( d2 ) ) {
331                case ALRC_SYMBOL:
332                        rc_symtostr0( d2, str2, 65 );
333                        break;
334                case ALRC_STRING:
335                        rc_tostr0( d2, str2, 65 );
336                        break;
337                default:
338                        return AL_FALSE;
339        }
340
341        if( strcmp(d1, d2) == 0 ) {
342                return AL_TRUE;
343        }
344
345        return AL_FALSE;
346}
347
348/*
349 * rc_lookup_list( Rcvar haystack, const char *needle )
350 *
351 * Evaluates needle and sees if it is a member in haystack, returning a list
352 * with the first conscell to have a matching car as its head.
353 */
354Rcvar rc_lookup_list( Rcvar haystack, const char *needle ) {
355        Rcvar rcneedle = rc_eval( needle );
356
357        return rc_member( haystack, rcneedle );
358}
359
360/*
361 * rc_foreach( Rcvar ls, Rcvar (*op)( Rcvar operand ))
362 *
363 * For each member in ls, apply op to the member.
364 */
365void rc_foreach( Rcvar ls, Rcvar (*op)(Rcvar operand) ) {
366        if( rc_type( ls ) != ALRC_CONSCELL ) {
367                _alDebug( ALD_CONFIG, __FILE__, __LINE__,
368                          "rc_foreach fail type = %s",
369                          rc_typestr( rc_type(ls )));
370
371                return;
372        }
373
374        op( rc_car(ls) );
375
376        rc_foreach( rc_cdr( ls ), op );
377
378        return;
379}
380
381/*
382 * rc_define_list( Rcvar ls )
383 *
384 * Creates a binding between car(ls) (symbol) the evaluation of cadr(ls) in the
385 * global scope, returning cadr(ls).
386 */
387Rcvar rc_define_list( Rcvar ls ) {
388        static char symname[65];
389
390        rc_symtostr0( rc_car(ls), symname, 65 );
391
392        return rc_define( symname, rc_cadr(ls) );
393}
394
395/*
396 * print_prim( Rcvar obj )
397 *
398 * Prints obj.
399 */
400static void print_prim( Rcvar obj ) {
401        Rcvar lcar;
402        Rcvar lcdr;
403
404        if(obj == NULL) {
405                /* FIXME */
406                return;
407        }
408
409        switch(rc_type(obj)) {
410                case ALRC_SYMBOL:
411                case ALRC_STRING:
412                        printf("%s ", ((AL_rctree *) obj)->data.str.c_str );
413                        break;
414                case ALRC_INTEGER:
415                        printf("%d ", ((AL_rctree *) obj)->data.i);
416                        break;
417                case ALRC_FLOAT:
418                        printf("%f ", ((AL_rctree *) obj)->data.f );
419                        break;
420                case ALRC_PRIMITIVE:
421                        printf("%p ", (void *) ((AL_rctree *) obj)->data.proc);
422                        break;
423                case ALRC_POINTER:
424                        printf("%p ", (void *) ((AL_rctree *) obj)->data.p);
425                        break;
426                case ALRC_BOOL:
427                        if(((AL_rctree *) obj)->data.b) {
428                                printf("#t ");
429                        } else {
430                                printf("#f ");
431                        }
432                        break;
433                case ALRC_CONSCELL:
434                        lcar = rc_car(obj);
435                        lcdr = rc_cdr(obj);
436
437                        if(rc_type(lcar) == ALRC_CONSCELL) {
438                                printf("(");
439                        } else {
440                                printf("( ");
441                        }
442
443                        print_prim(lcar);
444
445                        for( ; rc_type(lcdr) == ALRC_CONSCELL; lcdr = rc_cdr(lcdr)) {
446                                Rcvar temp = rc_car(lcdr);
447
448                                print_prim(temp);
449                        }
450
451                        if(lcdr) {
452                                if(lcdr == rc_cdr(obj)) {
453                                        /* pair */
454                                        printf(" . ");
455                                }
456
457                                print_prim(lcdr);
458                        }
459
460                        if(rc_type(lcdr) == ALRC_CONSCELL) {
461                                printf(") ");
462                        } else {
463                                printf(")");
464                        }
465                        break;
466                case ALRC_INVALID:
467                        assert( 0 );
468                        break;
469        }
470
471        return;
472}
473
474/*
475 * rc_print( Rcvar sym )
476 *
477 * Prints a stdout representation of sym to stdout.
478 */
479void rc_print( Rcvar sym ) {
480        print_prim( sym );
481
482        printf("\n");
483
484        return;
485}
486
487Rcvar alrc_quote( Rcvar val) {
488        AL_rctree *retval;
489
490        retval = _alRcTreeAlloc();
491        retval->type = ALRC_CONSCELL;
492
493        retval->data.ccell.car = _alRcTreeAlloc();
494        retval->data.ccell.car->type = ALRC_SYMBOL;
495        snprintf( retval->data.ccell.car->data.str.c_str, ALRC_MAXSTRLEN,
496                 "quote" );
497        retval->data.ccell.car->data.str.len = 5;
498
499        retval->data.ccell.cdr = val;
500
501        return retval;
502}
Note: See TracBrowser for help on using the repository browser.