00001 /* SVN FILE INFO 00002 * $Revision: 174 $ : Last Committed Revision 00003 * $Date: 2008年06月24日 10:50:29 -0700 (2008年6月24日) $ : Last Committed Date */ 00004 /*[ 00005 * Copyright (c) 2007 Integration Engineering Laboratory 00006 University of California, Davis 00007 * 00008 * Permission to use, copy, and distribute this software and its 00009 * documentation for any purpose with or without fee is hereby granted, 00010 * provided that the above copyright notice appear in all copies and 00011 * that both that copyright notice and this permission notice appear 00012 * in supporting documentation. 00013 * 00014 * Permission to modify the software is granted, but not the right to 00015 * distribute the complete modified source code. Modifications are to 00016 * be distributed as patches to the released version. Permission to 00017 * distribute binaries produced by compiling modified sources is granted, 00018 * provided you 00019 * 1. distribute the corresponding source modifications from the 00020 * released version in the form of a patch file along with the binaries, 00021 * 2. add special version identification to distinguish your version 00022 * in addition to the base release version number, 00023 * 3. provide your name and address as the primary contact for the 00024 * support of your modified version, and 00025 * 4. retain our contact information in regard to use of the base 00026 * software. 00027 * Permission to distribute the released version of the source code along 00028 * with corresponding source modifications in the form of a patch file is 00029 * granted with same provisions 2 through 4 for binary distributions. 00030 * 00031 * This software is provided "as is" without express or implied warranty 00032 * to the extent permitted by applicable law. 00033 ]*/ 00034 00035 /* Macro Synopses 00036 * 00037 * Error Checking 00038 * 00039 * CHECK_NULL(var, action) : Checks value of 'var' for NULL. If it is 00040 * null, an error message is printed to stderr and 'action' is 00041 * performed. 00042 * 00043 * Thread Creation/Cancellation 00044 * 00045 * GET_THREAD_MODE(started_threads, thread): Returns 1 if 'thread' is set 00046 * run in 'started_threads'. 00047 * SET_THREAD_ON(a, b) : Sets thread 'b' to 'on' in status 'a'. 00048 * SET_THREAD_OFF(a, b) : See SET_THREAD_ON 00049 * 00050 * Thread Syncronization 00051 * 00052 * MUTEX_T : Platform independant mutex data type. 00053 * COND_T : Platform independant condition variable data type. 00054 * MUTEX_INIT( mutex ) : Platform ind. mutex initialization. 00055 * COND_INIT(cond) : Platform ind. condition variable initialization. 00056 * MUTEX_DESTROY(mutex) : Platform ind. mutex variable destruction. 00057 * COND_DESTROY(cond) : Platform ind. cond variable destruction. 00058 * MUTEX_LOCK(mutex) : Locks mutex 'mutex'. 00059 * MUTEX_UNLOCK(mutex) : Unlocks mutex 'mutex'. 00060 * SIGNAL(cond, mutex, action) : Sends a signal to condition variable 00061 * 'cond' protected by mutex 'mutex'. Executes action 'action' after 00062 * locking mutex 'mutex' but before signalling the condition 00063 * variable. 00064 * WAKE_QUEUE(queue) : Signals and activates a thread sleeping on one 00065 * of the system queues. 00066 * COND_SLEEP(cond, mutex) : Causes a thread to sleep on a condition 00067 * variable 'cond', protected by 'mutex'. 00068 * COND_RESET(cond, mutex) : Resets condition variables after being 00069 * woken from COND_SLEEP. 00070 * 00071 * Ch Datatype Conversions 00072 * 00073 * CH_DATATYPE_SIZE(type, size) : Takes 'ChType_t type' as input, 00074 * fills 'size' with the byte size of 'type'. 00075 * CH_DATATYPE_STRING(type, string) : Takes 'ChType_t type' as input, 00076 * fills 'char* string' with a string of the type. 00077 * CH_STRING_DATATYPE(string, type) : Takes 'char* string' as input 00078 * and fills 'ChType_t type' 00079 * Ch_DATATYPE_STR_TO_VAL(type, string, val) : Takes 'ChType_t type' and 00080 * 'char* string' as input and fills 'void* val' with the value 00081 * contained within 'string'. 00082 */ 00083 #ifndef _MACROS_H_ 00084 #define _MACROS_H_ 00085 00086 #ifndef _WIN32 00087 #include <pthread.h> 00088 #include <semaphore.h> 00089 #include "config.h" 00090 #else 00091 #include <windows.h> 00092 #endif 00093 00094 /* * * * * * * * * * * * * * * 00095 * T H R E A D S T A T U S * 00096 * * * * * * * * * * * * * * */ 00097 00098 /************************************* 00099 * AI => Agent Initializing Thread * 00100 * AM => Agent Managing Thread * 00101 * CL => Connection Listening Thread * 00102 * DF => Directory Facilitator Thr. * 00103 * MR => Message Receiving Thread * 00104 * MS => Message Sending Thread * 00105 * CP => Command Prompt Thread * 00106 *************************************/ 00107 00108 /* GET_THREAD_MODE Macro: 00109 * Usage: GET_THREAD_MODE(runthreads, MC_THREAD_AM) 00110 * Returns 1 if thread is set to run, 0 otherwise. */ 00111 #define GET_THREAD_MODE(a, b) ( (a & (1<<b)) / (1<<b) ) 00112 00113 /* SET_THREAD_XXX(runthreads, XX_THREAD); */ 00114 #define SET_THREAD_ON(a, b) a = (a | (1<<b)) 00115 #define SET_THREAD_OFF(a, b) a = (a & (~(1<<b))) 00116 00117 00118 /* Struct Macro */ 00119 #define STRUCT( name, members ) \ 00120 typedef struct name##_s { \ 00121 members \ 00122 } name##_t; \ 00123 typedef name##_t* name##_p; 00124 00125 00126 /* * * * * * * * * * * * * 00127 * U N I X M A C R O S * 00128 * * * * * * * * * * * * */ /* Windows macros follow */ 00129 #ifndef _WIN32 00130 00131 /* ****** * 00132 * THREAD * 00133 * ****** */ 00134 #define PTHREAD_STACK_SIZE 131072 /* This is PTHREAD_STACK_MIN * 8 for me */ 00135 #define THREAD_T pthread_t 00136 #define THREAD_CREATE( thread_handle, function, arg ) \ 00137 pthread_create( \ 00138 thread_handle, \ 00139 &attr, \ 00140 function, \ 00141 (void*) arg \ 00142 ) 00143 00144 #define THREAD_CANCEL( thread_handle ) \ 00145 pthread_cancel( thread_handle ) 00146 00147 #define THREAD_JOIN(thread_handle ) \ 00148 pthread_join( thread_handle, NULL ) 00149 00150 /* ***** */ 00151 /* MUTEX */ 00152 /* ***** */ 00153 00154 /* Typedef */ 00155 #define MUTEX_T pthread_mutex_t 00156 /* Init */ 00157 #define MUTEX_INIT(mutex) \ 00158 pthread_mutex_init(mutex, NULL) 00159 /* Destroy */ 00160 #define MUTEX_DESTROY(mutex) \ 00161 pthread_mutex_destroy(mutex) 00162 /* functions */ 00163 #define MUTEX_LOCK(mutex) \ 00164 if (pthread_mutex_lock( mutex )) \ 00165 fprintf(stderr, "pthread lock error: %s:%d\n", __FILE__, __LINE__) 00166 #define MUTEX_UNLOCK(mutex) \ 00167 pthread_mutex_unlock( mutex ) 00168 #define MUTEX_NEW(mutex) \ 00169 mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); \ 00170 if (mutex == NULL) \ 00171 fprintf(stderr, "Memory Error. %s:%d\n", __FILE__,__LINE__); \ 00172 00173 /* **** * 00174 * COND * 00175 * **** */ 00176 /* Typedef */ 00177 #define COND_T pthread_cond_t 00178 /* Init */ 00179 #define COND_INIT(cond) \ 00180 pthread_cond_init(cond, NULL) 00181 /* Destroy */ 00182 #define COND_DESTROY(cond) \ 00183 pthread_cond_destroy(cond) 00184 /* functions */ 00185 #define COND_WAIT( cond , mutex ) \ 00186 pthread_cond_wait(cond, mutex ) 00187 /* Wait until 'test' is true */ 00188 #define COND_SLEEP( cond, mutex, test ) \ 00189 if (pthread_mutex_lock( mutex )) \ 00190 printf("pthread lock error: %s:%d\n", __FILE__, __LINE__); \ 00191 if (!test) { \ 00192 pthread_cond_wait( cond, mutex ); \ 00193 } 00194 #define COND_RESET( cond, mutex ) \ 00195 pthread_mutex_unlock( mutex ); 00196 #define COND_SLEEP_ACTION(cond, mutex, action) \ 00197 if (pthread_mutex_lock( mutex )) \ 00198 printf("pthread lock error: %s:%d\n", __FILE__, __LINE__); \ 00199 action; \ 00200 pthread_cond_wait( cond, mutex ); 00201 #define SIGNAL(cond, mutex, action) \ 00202 pthread_mutex_lock( mutex ); \ 00203 action; \ 00204 pthread_cond_signal( cond ); \ 00205 pthread_mutex_unlock( mutex ) 00206 #define COND_BROADCAST(cond) \ 00207 pthread_cond_broadcast( cond ) 00208 #define COND_SIGNAL(cond) \ 00209 pthread_cond_signal( cond ) 00210 00211 /* ********* * 00212 * SEMAPHORE * 00213 * ********* */ 00214 /* Typedef */ 00215 #define SEMAPHORE_T sem_t 00216 /* Init */ 00217 #define SEMAPHORE_INIT(sem) \ 00218 sem_init(sem, 0, 0) 00219 /* Destroy */ 00220 #define SEMAPHORE_DESTROY(sem) \ 00221 sem_destroy(sem) 00222 /* Functions */ 00223 #define SEMAPHORE_WAIT(sem) \ 00224 sem_wait(sem) 00225 #define SEMAPHORE_POST(sem) \ 00226 sem_post(sem) 00227 00228 /* ******* * 00229 * RW_LOCK * 00230 * ******* */ 00231 /* Typedef */ 00232 #ifdef HAVE_PTHREAD_RWLOCK_T 00233 #define RWLOCK_T pthread_rwlock_t 00234 #else 00235 #define RWLOCK_T mc_rwlock_t 00236 #endif 00237 /* Init */ 00238 #ifdef HAVE_PTHREAD_RWLOCK_T 00239 #define RWLOCK_INIT(rwlock) \ 00240 pthread_rwlock_init(rwlock, NULL) 00241 #else 00242 #define RWLOCK_INIT(rwlock) \ 00243 mc_rwlock_init(rwlock) 00244 #endif 00245 /* Destroy */ 00246 #ifdef HAVE_PTHREAD_RWLOCK_T 00247 #define RWLOCK_DESTROY(rwlock) \ 00248 pthread_rwlock_destroy(rwlock) 00249 #else 00250 #define RWLOCK_DESTROY(rwlock) \ 00251 mc_rwlock_destroy(rwlock) 00252 #endif 00253 /* Functions */ 00254 #ifdef HAVE_PTHREAD_RWLOCK_T 00255 #define RWLOCK_RDLOCK(rwlock) \ 00256 if (pthread_rwlock_rdlock(rwlock)) \ 00257 fprintf(stderr, "rwlock error: %s:%d\n", __FILE__, __LINE__) 00258 #define RWLOCK_RDUNLOCK(rwlock) \ 00259 if (pthread_rwlock_unlock(rwlock)) \ 00260 fprintf(stderr, "rwunlock error: %s:%d\n", __FILE__, __LINE__) 00261 #define RWLOCK_WRLOCK(rwlock) \ 00262 if (pthread_rwlock_wrlock(rwlock)) \ 00263 fprintf(stderr, "rwlock error: %s:%d\n", __FILE__, __LINE__) 00264 #define RWLOCK_WRUNLOCK(rwlock) \ 00265 if (pthread_rwlock_unlock(rwlock)) \ 00266 fprintf(stderr, "rwunlock error: %s:%d\n", __FILE__, __LINE__) 00267 #else 00268 #define RWLOCK_RDLOCK(rwlock) \ 00269 mc_rwlock_rdlock(rwlock) 00270 #define RWLOCK_RDUNLOCK(rwlock) \ 00271 mc_rwlock_rdunlock(rwlock) 00272 #define RWLOCK_WRLOCK(rwlock) \ 00273 mc_rwlock_wrlock(rwlock) 00274 #define RWLOCK_WRUNLOCK(rwlock) \ 00275 mc_rwlock_wrunlock(rwlock) 00276 #endif 00277 00278 00279 /* ***************** * 00280 * SYSTEM QUEUE SYNC * 00281 * ***************** */ 00282 #define WAKE_QUEUE(queue, action) \ 00283 if (pthread_mutex_trylock( queue->lock ) == 0) { \ 00284 action; \ 00285 pthread_cond_signal( queue->cond); \ 00286 pthread_mutex_unlock( queue->lock); \ 00287 } 00288 #define SLEEP_QUEUE( queue ) \ 00289 if (pthread_mutex_lock( queue->thread_mutex )) \ 00290 printf("pthread lock error: %s:%d\n", __FILE__, __LINE__); \ 00291 pthread_cond_wait( queue->touched_signal, queue->thread_mutex ) 00292 #define SLEEP_RESET( queue ) \ 00293 pthread_mutex_unlock( queue->thread_mutex ) 00294 00295 00296 00297 #else 00298 /* * * * * * * * * * * * * * * * 00299 * W I N D O W S M A C R O S * 00300 * * * * * * * * * * * * * * * */ 00301 00302 /* ******* * 00303 * THREADS * 00304 * ******* */ 00305 #define THREAD_T HANDLE 00306 #define THREAD_CREATE(thread_handle, function, arg) \ 00307 *(thread_handle) = CreateThread( \ 00308 NULL, \ 00309 (SIZE_T)stack_size, \ 00310 function, \ 00311 arg, \ 00312 0, \ 00313 NULL \ 00314 ) 00315 00316 #define THREAD_CANCEL(thread_handle) \ 00317 TerminateThread( thread_handle, 0) 00318 00319 #define THREAD_JOIN(thread_handle) \ 00320 WaitForSingleObject(thread_handle, INFINITE) 00321 00322 /* ***** */ 00323 /* MUTEX */ 00324 /* ***** */ 00325 /* Typedef */ 00326 #define MUTEX_T HANDLE 00327 /* Init */ 00328 #define MUTEX_INIT(mutex) \ 00329 *mutex = CreateMutex(NULL, FALSE, NULL) 00330 /* Destroy */ 00331 #define MUTEX_DESTROY(mutex) 00332 /* Functions */ 00333 #define MUTEX_LOCK(mutex) \ 00334 WaitForSingleObject( \ 00335 *mutex , \ 00336 INFINITE) 00337 #define MUTEX_UNLOCK(mutex) \ 00338 ReleaseMutex( *mutex ) 00339 #define MUTEX_NEW(mutex) \ 00340 mutex = (HANDLE*)malloc(sizeof(HANDLE)); \ 00341 if(mutex == NULL) \ 00342 fprintf(stderr, "Memory Error. %s:%d\n", __FILE__, __LINE__) 00343 00344 00345 /* **** * 00346 * COND * 00347 * **** */ 00348 /* Typedef */ 00349 #define COND_T HANDLE 00350 /* Init */ 00351 #define COND_INIT(cond) \ 00352 *cond = CreateEvent(NULL, TRUE, TRUE, NULL);\ 00353 ResetEvent(*cond) 00354 /* Destroy */ 00355 #define COND_DESTROY(cond) 00356 /* Functions */ 00357 00358 #define COND_WAIT( cond , mutex ) \ 00359 ResetEvent(*cond); \ 00360 ReleaseMutex(*mutex); \ 00361 WaitForSingleObject( *cond, INFINITE) 00362 #define COND_SLEEP( cond, mutex, test ) \ 00363 ResetEvent( *cond ); \ 00364 if (!test){ \ 00365 WaitForSingleObject( *cond, INFINITE); \ 00366 } 00367 #define COND_RESET( cond, mutex ) \ 00368 ResetEvent(*cond) 00369 #define COND_SLEEP_ACTION(cond, mutex, action) \ 00370 ResetEvent( *cond ); \ 00371 action; \ 00372 WaitForSingleObject( *cond, INFINITE) 00373 #define SIGNAL(cond, mutex, action) \ 00374 action; \ 00375 SetEvent( *cond ) 00376 #define COND_BROADCAST(cond) \ 00377 SetEvent(*cond) 00378 #define COND_SIGNAL(cond) \ 00379 SetEvent(*cond) 00380 00381 00382 /* ********* * 00383 * SEMAPHORE * 00384 * ********* */ 00385 /* Typedef */ 00386 #define SEMAPHORE_T HANDLE 00387 /* Init */ 00388 #define SEMAPHORE_INIT(sem) \ 00389 *sem = CreateSemaphore( \ 00390 NULL, \ 00391 0, \ 00392 1024, \ 00393 NULL ) 00394 /* Destroy */ 00395 #define SEMAPHORE_DESTROY(sem) 00396 /* Functions */ 00397 #define SEMAPHORE_WAIT(sem) \ 00398 WaitForSingleObject(sem, INFINITE) 00399 #define SEMAPHORE_POST(sem) \ 00400 ReleaseSemaphore(sem, 1, NULL) 00401 00402 00403 /* ******* * 00404 * RW_LOCK * 00405 * ******* */ 00406 /* Typedef */ 00407 #define RWLOCK_T mc_rwlock_t 00408 /* Init */ 00409 #define RWLOCK_INIT(rwlock) \ 00410 mc_rwlock_init(rwlock) 00411 /* Destroy */ 00412 #define RWLOCK_DESTROY(rwlock) mc_rwlock_destroy(rwlock) 00413 /* Functions */ 00414 #define RWLOCK_RDLOCK(rwlock) \ 00415 mc_rwlock_rdlock(rwlock) 00416 #define RWLOCK_RDUNLOCK(rwlock) \ 00417 mc_rwlock_rdunlock(rwlock) 00418 #define RWLOCK_WRLOCK(rwlock) \ 00419 mc_rwlock_wrlock(rwlock) 00420 #define RWLOCK_WRUNLOCK(rwlock) \ 00421 mc_rwlock_wrunlock(rwlock) 00422 00423 00424 /* ***************** * 00425 * SYSTEM QUEUE SYNC * 00426 * ***************** */ 00427 #define SLEEP_QUEUE( queue ) \ 00428 ResetEvent( *(queue->touched_signal) ); \ 00429 WaitForSingleObject( *(queue->touched_signal), INFINITE ) 00430 #define WAKE_QUEUE(queue, action) \ 00431 action; \ 00432 SetEvent( *(queue->cond)) 00433 #define SLEEP_RESET( queue ) 00434 00435 #endif /* End unix/windows macros */ 00436 00437 00438 00439 /* * * * * * * * * * * * * * * 00440 * M I S C E L L A N E O U S * 00441 * * * * * * * * * * * * * * */ 00442 /* Check to see if a data structure is NULL: Perform 'action' if it is null */ 00443 #define CHECK_NULL( var, action ) \ 00444 if ( var == NULL ) { \ 00445 fprintf(stderr, "Pointer var is null: expected otherwise.\n"); \ 00446 fprintf(stderr, "Error occured at %s:%d", __FILE__, __LINE__); \ 00447 action; \ 00448 } 00449 00450 #define WARN( message ) \ 00451 fprintf(stderr, "WARNING: "); \ 00452 fprintf(stderr, message ); \ 00453 fprintf(stderr, " %s:%d\n", __FILE__, __LINE__ ) 00454 00455 /* Macro for determining size of a CH data type */ 00456 /* Arguments: 00457 * type: CH_Type_t type 00458 * size: int 00459 * */ 00460 #define CH_DATATYPE_SIZE(type, size) \ 00461 switch(type) { \ 00462 case CH_CHARTYPE: \ 00463 size = sizeof(char); \ 00464 break; \ 00465 case CH_INTTYPE: \ 00466 size = sizeof(int); \ 00467 break; \ 00468 case CH_UINTTYPE: \ 00469 size = sizeof(unsigned int); \ 00470 break; \ 00471 case CH_SHORTTYPE: \ 00472 size = sizeof(short); \ 00473 break; \ 00474 case CH_USHORTTYPE: \ 00475 size = sizeof(unsigned short); \ 00476 break; \ 00477 case CH_FLOATTYPE: \ 00478 size = sizeof(float); \ 00479 break; \ 00480 case CH_DOUBLETYPE: \ 00481 size = sizeof(double); \ 00482 break; \ 00483 default: \ 00484 fprintf(stderr, "Unknown data type: %d at %s:%d", \ 00485 type, __FILE__, __LINE__); \ 00486 size=0; \ 00487 } 00488 00489 /* Macro for converting a CH_Type_t into a string */ 00490 /* Argument 'string' must be an allocated array of characters. */ 00491 #define CH_DATATYPE_STRING(type, string) \ 00492 switch(type) { \ 00493 case CH_CHARTYPE: \ 00494 strcpy(string, "char"); \ 00495 break; \ 00496 case CH_INTTYPE: \ 00497 strcpy(string, "int"); \ 00498 break; \ 00499 case CH_UINTTYPE: \ 00500 strcpy(string, "unsigned int"); \ 00501 break; \ 00502 case CH_SHORTTYPE: \ 00503 strcpy(string, "short"); \ 00504 break; \ 00505 case CH_USHORTTYPE: \ 00506 strcpy(string, "unsigned short"); \ 00507 break; \ 00508 case CH_FLOATTYPE: \ 00509 strcpy(string, "float"); \ 00510 break; \ 00511 case CH_DOUBLETYPE: \ 00512 strcpy(string, "double"); \ 00513 break; \ 00514 default: \ 00515 fprintf(stderr, \ 00516 "Unsupported data type: %d %s:%d\n", \ 00517 type, __FILE__, __LINE__ ); \ 00518 } 00519 00520 /* CH_DATATYPE_VALUE_STRING 00521 * A Macro for converting data pointed to by a pointer into 00522 * a string. */ 00523 #define CH_DATATYPE_VALUE_STRING(type, string, p) \ 00524 switch(type) { \ 00525 case CH_CHARTYPE: \ 00526 sprintf(string, "%c", *((char*)p)); \ 00527 break; \ 00528 case CH_INTTYPE: \ 00529 sprintf(string, "%d", *((int*)p)); \ 00530 break; \ 00531 case CH_UINTTYPE: \ 00532 sprintf(string, "%d", *((unsigned int*)p)); \ 00533 break; \ 00534 case CH_SHORTTYPE: \ 00535 sprintf(string, "%d", *((short*)p)); \ 00536 break; \ 00537 case CH_USHORTTYPE: \ 00538 sprintf(string, "%d", *((unsigned short*)p)); \ 00539 break; \ 00540 case CH_FLOATTYPE: \ 00541 sprintf(string, "%f", *((float*)p)); \ 00542 break; \ 00543 case CH_DOUBLETYPE: \ 00544 sprintf(string, "%f", *((double*)p)); \ 00545 break; \ 00546 default: \ 00547 fprintf(stderr, \ 00548 "Unsupported data type: %d %s:%d\n", \ 00549 type, __FILE__, __LINE__); \ 00550 } 00551 00552 #define CH_STRING_DATATYPE(string, type) \ 00553 if (!strcmp(string, "int")) { \ 00554 type = CH_INTTYPE; \ 00555 } else if (!strcmp(string, "float")) { \ 00556 type = CH_FLOATTYPE; \ 00557 } else if (!strcmp(string, "double")) { \ 00558 type = CH_DOUBLETYPE; \ 00559 } else if (!strcmp(string, "unsigned int")) { \ 00560 type = CH_UINTTYPE; \ 00561 } else if (!strcmp(string, "short")) { \ 00562 type = CH_SHORTTYPE; \ 00563 } else if (!strcmp(string, "unsigned short")) { \ 00564 type = CH_USHORTTYPE; \ 00565 } else if (!strcmp(string, "char")) { \ 00566 type = CH_CHARTYPE; \ 00567 } else { \ 00568 fprintf(stderr, \ 00569 "Unsupported data type: %d %s:%d\n", \ 00570 type, __FILE__, __LINE__ ); \ 00571 } 00572 00573 #ifndef _WIN32 00574 #define CH_DATATYPE_STR_TO_VAL(type, string, val) \ 00575 switch (type) { \ 00576 case CH_INTTYPE: \ 00577 *(int*)val = atoi(string); \ 00578 break; \ 00579 case CH_UINTTYPE: \ 00580 *(unsigned int*)val = atoi(string); \ 00581 break; \ 00582 case CH_SHORTTYPE: \ 00583 *(short*)val = (short)atoi(string); /*FIXME*/ \ 00584 break; \ 00585 case CH_USHORTTYPE: \ 00586 *(unsigned short*)val = (unsigned short)atoi(string); /*FIXME*/ \ 00587 break; \ 00588 case CH_FLOATTYPE: \ 00589 *(float*)val = strtof(string, NULL); \ 00590 break; \ 00591 case CH_DOUBLETYPE: \ 00592 *(double*)val = strtod(string, NULL); \ 00593 break; \ 00594 default: \ 00595 fprintf(stderr, \ 00596 "Unsupported data type: %d %s:%d\n", \ 00597 type, __FILE__, __LINE__ ); \ 00598 } 00599 #else 00600 #define CH_DATATYPE_STR_TO_VAL(type, string, val) \ 00601 switch (type) { \ 00602 case CH_INTTYPE: \ 00603 *(int*)val = atoi(string); \ 00604 break; \ 00605 case CH_UINTTYPE: \ 00606 *(unsigned int*)val = atoi(string); \ 00607 break; \ 00608 case CH_SHORTTYPE: \ 00609 *(short*)val = (short)atoi(string); /*FIXME*/ \ 00610 break; \ 00611 case CH_USHORTTYPE: \ 00612 *(unsigned short*)val = (unsigned short)atoi(string); /*FIXME*/ \ 00613 break; \ 00614 case CH_FLOATTYPE: \ 00615 *(float*)val = (double)strtod(string, NULL); \ 00616 break; \ 00617 case CH_DOUBLETYPE: \ 00618 *(double*)val = strtod(string, NULL); \ 00619 break; \ 00620 default: \ 00621 fprintf(stderr, \ 00622 "Unsupported data type: %d %s:%d\n", \ 00623 type, __FILE__, __LINE__ ); \ 00624 } 00625 #endif 00626 00627 00628 #endif