Main Page   Compound List   File List   Compound Members   File Members  

type.c

00001 /* DICElib (DIstributed CAVE Engine library) 
00002  * Copyright (c) 2001 Bruno Barberi Gnecco <brunobg@lsi.usp.br>
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to
00006  * deal in the Software without restriction, including without limitation the
00007  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00008  * sell copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies of the Software, its documentation and marketing & publicity
00013  * materials, and acknowledgment shall be given in the documentation, materials
00014  * and software packages that this Software was used.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00019  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00020  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00021  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022  */
00023 
00024 #include "_dicelib.h"
00025 #include "hash.h"
00026 #include <string.h>
00027 #include <stdlib.h>
00028 #include <errno.h>
00029 #ifndef WINDOWS
00030 # ifdef USE_LTDL
00031 #  include <ltdl.h>
00032 # endif
00033 #ifdef HAVE_IEEE754_H
00034 #include <ieee754.h>
00035 #endif /* HAVE_IEEE754_H */
00036 #endif /* WINDOWS */
00037 
00038 static HashTable dice_type_table;
00039 
00040 struct _dice_type {
00041         char *          (*pack_func) (void *data, int *n);
00042         void *          (*unpack_func) (char *data, int *n);
00043         void            (*free_func) (void *data);
00044 };
00045 
00046 int dice_type_is_valid ( char *type ) {
00047         if ( hash_data(&dice_type_table, type) )
00048                 return 1;
00049         return 0;
00050 }
00051 
00052 #define FUNCTION                "DICE_type_register"
00053 
00092 #ifdef USE_LTDL
00093 int DICE_type_register ( char *type ) {
00094         struct _dice_type       *dt;
00095         char                    *buffer;
00096         int                     len;
00097 
00098         _dice_debug(3, dice_printf(FUNCTION, "(%s)\n", type);)
00099 
00100         if ( !type ) {
00101                 _dice_debug(1, dice_printf(FUNCTION, "NULL type name\n");)
00102                 return -1;
00103         }
00104 
00105         dt = (struct _dice_type *)malloc(sizeof(struct _dice_type));
00106         if ( !dt ) {
00107                 _dice_debug(1, dice_printf(FUNCTION, "NULL malloc\n");)
00108                 return -1;
00109         }
00110 
00111         len = strlen(type)+1+7;
00112         buffer = (char *)malloc(len*sizeof(char));
00113         if ( !buffer ) {
00114                 _dice_debug(1, dice_printf(FUNCTION, "NULL malloc2\n");)
00115                 return -1;
00116         }
00117         strcpy(buffer, type);
00118         strcat(buffer, "_pack");
00119         dt->pack_func = lt_dlsym(dice_data.handle, buffer);
00120         if ( !dt->pack_func ) {
00121                 _dice_debug(1, dice_printf(FUNCTION, "_pack: %s\n", lt_dlerror());)
00122                 return -1;
00123         }
00124         strcpy(buffer, type);
00125         strcat(buffer, "_unpack");
00126         dt->unpack_func = lt_dlsym(dice_data.handle, buffer);
00127         if ( !dt->unpack_func ) {
00128                 _dice_debug(1, dice_printf(FUNCTION, "_unpack: %s\n", lt_dlerror());)
00129                 return -1;
00130         }
00131         strcpy(buffer, type);
00132         strcat(buffer, "_free");
00133         dt->free_func = lt_dlsym(dice_data.handle, buffer);
00134         if ( !dt->free_func ) {
00135                 _dice_debug(1, dice_printf(FUNCTION, "_free: %s\n", lt_dlerror());)
00136                 return -1;
00137         }
00138 
00139         if ( hash_insert(&dice_type_table, type, (void *)dt) == -1 ) {
00140                 _dice_debug(1, dice_printf(FUNCTION, "HashInsert returned -1 name\n");)
00141                 return -1;
00142         }
00143         free(buffer);
00144         return 0;
00145 }
00146 #else /* don't USE_LTDL */
00147 int dice_type_register ( DICE_Type *t ) {
00148         struct _dice_type       *dt;
00149 
00150         _dice_debug(3, dice_printf(FUNCTION, "(%p)\n", t);)
00151 
00152         if ( !t ) {
00153                 _dice_debug(1, dice_printf(FUNCTION, "NULL type name\n");)
00154                 return -1;
00155         }
00156 
00157         if ( !t->name || !t->pack_func || !t->unpack_func || !t->free_func ) {
00158                 _dice_debug(1, dice_printf(FUNCTION, "NULL pack, unpack or free function.");)
00159                 return -1;
00160         }
00161 
00162         dt = (struct _dice_type *)malloc(sizeof(struct _dice_type));
00163         if ( !dt ) {
00164                 _dice_debug(1, dice_printf(FUNCTION, "NULL malloc\n");)
00165                 return -1;
00166         }
00167         dt->pack_func = t->pack_func;
00168         dt->unpack_func = t->unpack_func;
00169         dt->free_func = t->free_func;
00170         if ( hash_insert(&dice_type_table, t->name, (void *)dt) == -1 ) {
00171                 _dice_debug(1, dice_printf(FUNCTION, "HashInsert returned -1 name\n");)
00172                 return -1;
00173         }
00174         return 0;
00175 }
00176 #endif
00177 
00178 #undef FUNCTION
00179 #define FUNCTION                "DICE_type_free"
00180 
00191 int DICE_type_free ( char *type, void *data ) {
00192         struct _dice_type       *dt;
00193 
00194         _dice_debug(3, dice_printf(FUNCTION, "(%s,%p)\n", 
00195                         type, data);)
00196 
00197         if ( !type ) {
00198                 _dice_debug(1, dice_printf(FUNCTION, "NULL type name\n");)
00199                 return -1;
00200         }
00201         if ( (dt = hash_data(&dice_type_table, type)) == NULL ) {
00202                 _dice_debug(1, dice_printf(FUNCTION, "type %s not found\n");)
00203                 return -1;
00204         }
00205         if ( dt->free_func )
00206                 dt->free_func(data);
00207         return 0;
00208 }
00209 
00210 #undef FUNCTION
00211 #define FUNCTION                "DICE_type_pack"
00212 
00225 char *DICE_type_pack ( char *type, void *data, int *n ) {
00226         struct _dice_type       *dt;
00227 
00228         _dice_debug(3, dice_printf(FUNCTION, "(%s,%p)\n", 
00229                         type, data);)
00230 
00231         if ( !type ) {
00232                 _dice_debug(1, dice_printf(FUNCTION, "NULL type name\n");)
00233                 return NULL;
00234         }
00235         if ( (dt = hash_data(&dice_type_table, type)) == NULL ) {
00236                 _dice_debug(1, dice_printf(FUNCTION, "type %s not found\n");)
00237                 return NULL;
00238         }
00239         return dt->pack_func(data, n);
00240 }
00241 
00242 
00243 #undef FUNCTION
00244 #define FUNCTION                "DICE_type_unpack"
00245 
00255 void *DICE_type_unpack ( char *type, char *packet, int *n ) {
00256         struct _dice_type       *dt;
00257 
00258         _dice_debug(3, dice_printf(FUNCTION, "(%s,%p)\n", 
00259                         type, packet);)
00260 
00261         if ( !type ) {
00262                 _dice_debug(1, dice_printf(FUNCTION, "NULL type name\n");)
00263                 return NULL;
00264         }
00265         if ( (dt = hash_data(&dice_type_table, type)) == NULL ) {
00266                 _dice_debug(1, dice_printf(FUNCTION, "type %s not found\n");)
00267                 return NULL;
00268         }
00269 
00270         return dt->unpack_func(packet, n);
00271 }
00272 
00273 /*
00274  * The default packers and unpackers.
00275  */
00276 
00277 /* so it won't segfault for nothing */
00278 void dice_free ( void *data ) {
00279         _dice_debug(4, dice_printf("dice_free", "(%p)\n", data);)
00280         if ( data )
00281                 free(data);
00282 }
00283 
00284 /* unsigned_char */
00285 char *unsigned_char_pack        ( void *data, int *n ) {
00286         char                    *buf;
00287         buf = malloc(4);
00288         if ( !buf || !data ) {
00289                 *n = -1;
00290                 return NULL;
00291         }
00292         memset(buf, 0, 4);
00293         buf[3] = *(unsigned char *)data;
00294         *n = 4;
00295         return buf;
00296 }
00297 void *unsigned_char_unpack      ( char *data, int *n ) {
00298         unsigned char           *c;
00299         c = (unsigned char *)malloc(1);
00300         if ( !c )
00301                 return NULL;
00302         *c = data[3];
00303         *n = 4;
00304         return (void *)c;
00305 }
00306 void unsigned_char_free         ( void *data ) {
00307         dice_free(data);
00308 }
00309 
00310 /* signed_char */
00311 char *signed_char_pack  ( void *data, int *n ) {
00312         return unsigned_char_pack(data, n);
00313 }
00314 void *signed_char_unpack        ( char *data, int *n ) {
00315         return unsigned_char_unpack(data, n);
00316 }
00317 void signed_char_free           ( void *data ) {
00318         dice_free(data);
00319 }
00320 
00321 /* unsigned_short */
00322 char *unsigned_short_pack       ( void *data, int *n ) {
00323         char                    *buf;
00324         unsigned short          *s;
00325         buf = malloc(4);
00326         if ( !buf || !data ) {
00327                 *n = -1;
00328                 return NULL;
00329         }
00330         memset(buf, 0, 4);
00331         s = (unsigned short *)data;
00332         buf[3] = (char) (*s) & 0xFF;
00333         buf[2] = (char)((*s)>>8) & 0xFF;
00334         *n = 4;
00335         return buf;
00336 }
00337 void *unsigned_short_unpack     ( char *data, int *n ) {
00338         unsigned short          *s;
00339         s = (unsigned short *)malloc(sizeof(unsigned short));
00340         if ( !s )
00341                 return NULL;
00342         *s = (unsigned short)(data[3]&0xFF) + ((data[2] << 8)&0xFF00);
00343         *n = 4;
00344         return (void *)s;
00345 }
00346 void unsigned_short_free        ( void *data ) {
00347         dice_free(data);
00348 }
00349 
00350 /* signed_short */
00351 char *signed_short_pack         ( void *data, int *n ) {
00352         return unsigned_short_pack(data, n);
00353 }
00354 void *signed_short_unpack       ( char *data, int *n ) {
00355         return unsigned_short_unpack(data, n);
00356 }
00357 void signed_short_free          ( void *data ) {
00358         dice_free(data);
00359 }
00360 
00361 /* unsigned long */
00362 char *unsigned_long_pack        ( void *data, int *n ) {
00363         char                    *buf;
00364         unsigned long           *l;
00365         l = (unsigned long *)data;
00366         buf = malloc(4);
00367         if ( !buf || !data ) {
00368                 *n = -1;
00369                 return NULL;
00370         }
00371         buf[3] = (char)(*l)&0xFF;
00372         buf[2] = (char)((*l)>>8)&0xFF;
00373         buf[1] = (char)((*l)>>16)&0xFF;
00374         buf[0] = (char)((*l)>>24)&0xFF;
00375         *n = 4;
00376         return buf;
00377 }
00378 void *unsigned_long_unpack      ( char *data, int *n ) {
00379         unsigned long           *l;
00380         l = (unsigned long *)malloc(sizeof(unsigned long));
00381         if ( !l )
00382                 return NULL;
00383         *l = (unsigned long)(data[3]&0xFF) + ((data[2] << 8)&0xFF00) + 
00384                 ((data[1] << 16)&0xFF0000) + ((data[0] << 24)&0xFF000000);
00385         *n = 4;
00386         
00387         return (void *)l;
00388 }
00389 void unsigned_long_free         ( void *data ) {
00390         dice_free(data);
00391 }
00392 
00393 /* signed_long */
00394 char *signed_long_pack          ( void *data, int *n ) {
00395         return unsigned_long_pack(data, n);
00396 }
00397 void *signed_long_unpack        ( char *data, int *n ) {
00398         return unsigned_long_unpack(data, n);
00399 }
00400 void signed_long_free           ( void *data ) {
00401         dice_free(data);
00402 }
00403 
00404 static char _digit_encode       ( char c ) {
00405         if ( c >= '0' && c <= '9' )
00406                 return c - 48;
00407         else if ( c == '-' )
00408                 return 0xA;
00409         else if ( c == '+' )
00410                 return 0xB;
00411         else if ( c == 'e' || c == 'E' )
00412                 return 0xC;
00413         else if ( c == '.' )
00414                 return 0xD;
00415         else if ( c == ' ' )
00416                 return 0xE;
00417         else { /* should NEVER happen */
00418                 return 0xF;
00419         }
00420 }
00421 static char _digit_decode       ( char d ) {
00422         if ( d >= 0 && d <= 9 )
00423                 return d + 48;
00424         else if ( d == 0xA )
00425                 return '-';
00426         else if ( d == 0xB )
00427                 return '+';
00428         else if ( d == 0xC )
00429                 return 'e';
00430         else if ( d == 0xD )
00431                 return '.';
00432         else if ( d == 0xE )
00433                 return ' ';
00434         else { /* should NEVER happen */
00435                 return ' ';
00436         }
00437 }
00438 
00439 /* float, transfer using printf */
00440 char *float_pack                ( void *data, int *n ) {
00441         char                    *buf;
00442         char                    temp[13];
00443         float                   f;
00444         int                     i;
00445 
00446         f = *(float *)data;
00447         buf = (char *)malloc(6);
00448         if ( !buf ) {
00449                 *n = -1;
00450                 return NULL;
00451         }
00452         snprintf(temp, 13, "%#.5e", f);
00453         for ( i = 0; i < 6; i++ )
00454                 buf[i] = (_digit_encode(temp[i<<1]))+
00455                          (_digit_encode(temp[(i<<1)+1])<<4);
00456         *n = 6;
00457         return buf;
00458 }
00459 void *float_unpack              ( char *data, int *n ) {
00460         float                   *g;
00461         char                    temp[13];
00462         int                     i;
00463 
00464         g = (float *)malloc(sizeof(float));
00465         if ( !g )
00466                 return NULL;
00467         for ( i = 0; i < 6; i++ ) {
00468                 temp[i<<1] = _digit_decode(data[i] & 0xF);
00469                 temp[(i<<1)+1] = _digit_decode((data[i]>>4) & 0xF);
00470         }
00471         temp[12] = '\0';
00472         *n = 6;
00473         *g = (float)strtod(temp, NULL);
00474         return g;
00475 }
00476 void float_free         ( void *data ) {
00477         dice_free(data);
00478 }
00479 
00480 /* double, transfer using printf */
00481 char *double_pack               ( void *data, int *n ) {
00482         char                    *buf;
00483         char                    temp[23];
00484         double                  f;
00485         int                     i;
00486 
00487         f = *(double *)data;
00488         buf = (char *)malloc(12);
00489         if ( !buf ) {
00490                 *n = -1;
00491                 return NULL;
00492         }
00493         snprintf(buf, 23, "%#.15e", f);
00494         for ( i = 0; i < 12; i++ )
00495                 buf[i] = (_digit_encode(temp[i<<1]))+
00496                          (_digit_encode(temp[(i<<1)+1])<<4);
00497         *n = 12;
00498         return buf;
00499 }
00500 void *double_unpack             ( char *data, int *n ) {
00501         double                  *g;
00502         char                    temp[23];
00503         int                     i;
00504 
00505         g = (double *)malloc(sizeof(double));
00506         if ( !g )
00507                 return NULL;
00508         for ( i = 0; i < 6; i++ ) {
00509                 temp[i<<1] = _digit_decode(data[i] & 0xF);
00510                 temp[(i<<1)+1] = _digit_decode((data[i]>>4) & 0xF);
00511         }
00512         temp[22] = '\0';
00513         *n = 12;
00514         *g = (double)strtod(data, NULL);
00515         return g;
00516 }
00517 void double_free                ( void *data ) {
00518         dice_free(data);
00519 }
00520 
00521 #ifdef HAVE_IEEE754_H
00522 /* float as defined in ieee754. Needs ieee754.h. */
00523 char *float754_pack             ( void *data, int *n ) {
00524         char                    *buf;
00525         union ieee754_float     f;
00526 
00527         f.f = *(float *)data;
00528         buf = (char *)malloc(4);
00529         if ( !buf ) {
00530                 *n = -1;
00531                 return NULL;
00532         }
00533         buf[0] = (f.ieee.negative<<7) | ((f.ieee.exponent>>1)&0x7F);
00534         buf[1] = ((f.ieee.exponent&0x01)<<7) | ((f.ieee.mantissa>>16)&0x7F);
00535         buf[2] = (f.ieee.mantissa>>8) & 0xFF;
00536         buf[3] = (f.ieee.mantissa)&0xFF;
00537         *n = 4;
00538         return buf;
00539 }
00540 void *float754_unpack           ( char *data, int *n ) {
00541         union ieee754_float     f;
00542         float                   *g;
00543         g = (float *)malloc(sizeof(float));
00544         if ( !g )
00545                 return NULL;
00546         f.ieee.negative = data[0]>>7;
00547         f.ieee.exponent = ((data[0]<<1)&0xFE) + ((data[1]>>7)&0x01);
00548         f.ieee.mantissa = (data[3]&0xFF) + ((data[2]<<8)&0xFF00) + 
00549                         (((data[1]&0x7F)<<16)&0xFF0000);
00550         *n = 4;
00551         *g = f.f;
00552         return g;
00553 }
00554 void float754_free              ( void *data ) {
00555         dice_free(data);
00556 }
00557 
00558 /* double as defined in ieee754. Needs ieee754.h. */
00559 char *double754_pack    ( void *data, int *n ) {
00560         char                    *buf;
00561         union ieee754_double    d;
00562 
00563         d.d = *(double *)data;
00564         buf = (char *)malloc(8);
00565         if ( !buf ) {
00566                 *n = -1;
00567                 return NULL;
00568         }
00569         buf[0] = (d.ieee.negative<<7) + ((d.ieee.exponent>>4)&0x7F);
00570         buf[1] = (((d.ieee.exponent)<<4)&0xF0) + ((d.ieee.mantissa0>>16)&0x0F);
00571         buf[2] = (d.ieee.mantissa0>>8) & 0xFF;
00572         buf[3] = (d.ieee.mantissa0)&0xFF;
00573         buf[4] = (d.ieee.mantissa1>>24) & 0xFF;
00574         buf[5] = (d.ieee.mantissa1>>16) & 0xFF;
00575         buf[6] = (d.ieee.mantissa1>>8) & 0xFF;
00576         buf[7] = (d.ieee.mantissa1) & 0xFF;
00577         *n = 8;
00578         return buf;
00579 }
00580 void *double754_unpack          ( char *data, int *n ) {
00581         union ieee754_double    d;
00582         double                  *e;
00583         e = (double *)malloc(sizeof(double));
00584         if ( !e ) {
00585                 return NULL;
00586         }
00587         d.ieee.negative = data[0]>>7;
00588         d.ieee.exponent = ((data[0]<<4)&0x7F0) + ((data[1]>>4)&0x0F);
00589         d.ieee.mantissa0 = (data[3]&0xFF) + ((data[2]<<8)&0xFF00) 
00590                         + (((data[1]&0x0F)<<16)&0xFF0000);
00591         d.ieee.mantissa1 = (data[7]&0xFF) + ((data[6]<<8)&0xFF00)
00592                         + ((data[5]<<16)&0xFF0000) + ((data[4]<<24)&0xFF000000);
00593         *n = 8;
00594         *e = d.d;
00595         return e;
00596 }
00597 void double754_free             ( void *data ) {
00598         dice_free(data);
00599 }
00600 #endif
00601 
00602 /* string */
00603 char *string_pack               ( void *data, int *n ) {
00604         char                    *buf;
00605         int                     length, total;
00606 
00607         length = strlen((char *)data);
00608         total = length + 4-(length%4 == 0 ? 4 : length %4) + 4; /* make it mod4=0 to conform with RFC1014 */
00609         buf = (char *)malloc(total);
00610         if ( !buf )
00611                 dice_printf(NULL, "error");
00612         memset(buf, 0, total);
00613         buf[3] = (char)(length)&0xFF;   
00614         buf[2] = (char)((length)>>8)&0xFF;
00615         buf[1] = (char)((length)>>16)&0xFF;
00616         buf[0] = (char)((length)>>24)&0xFF;
00617         memcpy(buf+4, data, length);
00618         *n = total;
00619         return buf;
00620 }
00621 void *string_unpack             ( char *data, int *n ) {
00622         char                    *buf;
00623         int                     length;
00624         length = (int)(data[3]&0xFF) + (((int)data[2] << 8)&0xFF00) + 
00625                 (((int)data[1] << 16)&0xFF0000) + (((int)data[0] << 24)&0xFF000000);
00626 
00627         buf = malloc(length+1);
00628         if ( !buf ) {
00629                 dice_printf("awer", "%s", strerror(errno));
00630         }
00631         memcpy(buf, data+4, length);
00632         buf[length] = '\0';
00633         *n = length + 4-(length%4 == 0 ? 4 : length %4) + 4;
00634         return (void *)buf;
00635 }
00636 void string_free                ( void *data ) {
00637         dice_free(data);
00638 }
00639 
00640 #undef FUNCTION
00641 #define FUNCTION                "dice_default_types"
00642 int dice_type_init_defaults ( void ) {
00643 #ifdef USE_LTDL
00644         char *default_names[] = {
00645                 "unsigned_char",
00646                 "signed_char",
00647                 "unsigned_short",
00648                 "signed_short",
00649                 "unsigned_long",
00650                 "signed_long",
00651                 "float", 
00652                 "double",
00653 #ifdef HAVE_IEEE754_H
00654                 "float754", 
00655                 "double754",
00656 #endif
00657                 "string"
00658         };
00659 #else /* do not USE_LTDL */
00660         DICE_Type default_types[] = {
00661                 { "unsigned_char", unsigned_char_pack, unsigned_char_unpack, unsigned_char_free },
00662                 { "signed_char", signed_char_pack, signed_char_unpack, signed_char_free },
00663                 { "unsigned_short", unsigned_short_pack, unsigned_short_unpack, unsigned_short_free },
00664                 { "signed_short", signed_short_pack, signed_short_unpack, signed_short_free },
00665                 { "unsigned_long", unsigned_long_pack, unsigned_long_unpack, unsigned_long_free },
00666                 { "signed_long", signed_long_pack, signed_long_unpack, signed_long_free },
00667                 { "float", float_pack, float_unpack, float_free },
00668                 { "double", double_pack, double_unpack, double_free },
00669 #ifdef HAVE_IEEE754_H
00670                 { "float754", float754_pack, float754_unpack, float754_free },
00671                 { "double754", double754_pack, double754_unpack, double754_free },
00672 #endif
00673                 { "string", string_pack, string_unpack, string_free } };
00674         DICE_Type *t;
00675 #endif
00676         int i;
00677 
00678         _dice_debug(3, dice_printf(FUNCTION, "\n");)
00679 
00680         hash_init(&dice_type_table, 64, NULL);
00681         for ( i = 0; i < sizeof(default_types)/sizeof(DICE_Type); i++ ) {
00682 #ifdef USE_LTDL 
00683                 if ( DICE_type_register(default_names[i]) == -1 ) {
00684                         _dice_debug(1, dice_printf(FUNCTION, "Could not register %s\n", default_names[i]);)
00685 #else
00686                 if ( dice_type_register(&default_types[i]) == -1 ) {
00687                         _dice_debug(1, dice_printf(FUNCTION, "Could not register %s\n", default_types->name);)
00688 #endif
00689                         return -1;
00690                 }
00691         }
00692 #ifndef USE_LTDL
00693         t = DICE_MyTypes;
00694         while (t->name) {
00695                 if ( dice_type_register(t) == -1 ) {
00696                         _dice_debug(1, dice_printf(FUNCTION, "Could not register %s\n", t->name);)
00697                         return -1;
00698                 }
00699                 t++;
00700         }
00701 #endif
00702         return 0;  
00703 }
00704 
00705 void dice_type_free_all ( void ) {
00706         hash_free(&dice_type_table, dice_free);
00707 }

Generated at Sun Dec 9 16:13:18 2001 for dicelib by doxygen1.2.9.1 written by Dimitri van Heesch, © 1997-2001