00001 /* ========================================================================= */ 00002 /* EGlib "Efficient General Library" provides some basic structures and 00003 * algorithms commons in many optimization algorithms. 00004 * 00005 * Copyright (C) 2005 Daniel Espinoza and Marcos Goycoolea. 00006 * 00007 * This library is free software; you can redistribute it and/or modify it 00008 * under the terms of the GNU Lesser General Public License as published by the 00009 * Free Software Foundation; either version 2.1 of the License, or (at your 00010 * option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, but 00013 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 00014 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00015 * License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public License 00018 * along with this library; if not, write to the Free Software Foundation, 00019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00020 * */ 00021 /* ========================================================================= */ 00022 /** @defgroup EGmacros General Macros 00023 * global macros and types for EGlib 00024 * 00025 * @version 0.9.2 00026 * @par History: 00027 * - 2007-01-19 00028 * - Delete EGosGetOffset 00029 * - 2006-09-28 00030 * - Add function that display basic process information, including 00031 * version and date of compilation of EGlib 00032 * - 2005-12-19 00033 * - Add float128 support ussing SoftFloat. 00034 * - 2005-10-28 00035 * - Add some status definitions for algorithms. 00036 * - 2005-06-14 00037 * - Add strdup definition, just for cleanliness when compiling 00038 * - 2005-05-23 00039 * - Add EGcontainerOf 00040 * - 2005-05-03 00041 * - Add typeof definition; 00042 * - 2004-07-14 00043 * - Add GNU_MP_Z GNU_MP_F and GNU_MP_Q to the type definitions. 00044 * - 2004-07-12 00045 * - Add EGRAT_TYPE to the type definitions. 00046 * - 2004-03-17 00047 * - Add TESTG that if recives something that is nonzero print an 00048 * user message and the go to the given location. 00049 * - 2004-02-05 00050 * - Add CHECKRVALG that checks a return value, display a mesage, 00051 * and then perform a goto. 00052 * - 2003-12-01 00053 * - Add definition of a 'copy' function and its MP version. 00054 * - 2003-11-20 00055 * - Add PTRTEST that check if a pointer points to the first 64Kb of 00056 * memory internal memory. Althought such situation may happend 00057 * (if we work in kernel-related stuff), it is usually an error 00058 * when we try to access such a memory. 00059 * - 2003-09-08 00060 * - Add ADVTESTL 00061 * - 2003-07-10 00062 * - Add MESSAGEF, ADVCHECKRVAL 00063 * - 2003-07-02 00064 * - Add EGosGetData, EGosSetData, EGosGetOffset 00065 * - 2003-06-16 00066 * - Add EXITL macro 00067 * - 2003-06-06 00068 * - Add TESTL macro to test conditions but only when the debug 00069 * level is at least some value 00070 * - 2003-05-22 00071 * - Add EXITRVAL 00072 * - 2003-05-15 00073 * - Add CHECKRVAL MESSAGE and WARNING macros. 00074 * - 2003-05-08 00075 * - Add support for variadic macros for EXIT and TEST 00076 * - Define EGRAND_MAX for SUN and LINUX acordingly, this is becouse 00077 * for some reason the value of RAND_MAX in SUN is not as 00078 * specified in stdlib.h but rather 1 << 31 - 1. Still I am not 00079 * sure about the maximum value of rand() on sun... will fix that 00080 * later on to. 00081 * - Add a mesage macro, it only print if the debug level is as high 00082 * as required by the first field. Again the definition is 00083 * variadric and if the debug level is 0 we reduce the macro to 00084 * the empty instruction. 00085 * 00086 * */ 00087 /** @{*/ 00088 /** @file 00089 * */ 00090 /* ========================================================================= */ 00091 00092 #ifndef __EG_MACROS_H__ 00093 #define __EG_MACROS_H__ 00094 #include <stdlib.h> 00095 #include <stdio.h> 00096 #include <errno.h> 00097 #include "eg_config.h" 00098 00099 /* ========================================================================= */ 00100 /** @brief We define the GNU C extension typeof if necesary. */ 00101 #ifndef typeof 00102 #define typeof __typeof__ 00103 #endif 00104 00105 /* ========================================================================= */ 00106 /** @brief return the offset of a member inside a structure. 00107 * @param type the type of the containing structure. 00108 * @param member the name of the member that we are interested in compute the 00109 * offset. 00110 * @return the number of bytes between the member and the beginning of the 00111 * structure. */ 00112 #define EGoffsetOf(type,member) ((size_t) &((type *)0)->member) 00113 00114 /* ========================================================================= */ 00115 /** @brief given a pointer to a member of a structure, return the pointer to 00116 * the head of the structure. (idea taken from Linux Kernel). 00117 * @param ptr pointer to the member of the containing structure. 00118 * @param type name type of the containing structure. 00119 * @param member name of the given member in the containing structure. 00120 * @return pointer to the containing structure. 00121 * */ 00122 #define EGcontainerOf(ptr,type,member) ({\ 00123 typeof(((type *)0)->member) *const __EGcOf_ptr = (ptr);\ 00124 (type *)( (char*)__EGcOf_ptr - ((size_t) &((type *)0)->member));}) 00125 00126 /* ========================================================================= */ 00127 /** @name External C-library functions: 00128 * Here we define some C-library functions that for some weird reason can't 00129 * be found at compile time but are present at linking time */ 00130 /*@{*/ 00131 extern void srandom (unsigned int); 00132 extern long random (void); 00133 extern double drand48 (void); 00134 extern long lrand48 (void); 00135 extern char *optarg; 00136 extern int getopt (int, 00137 char *const *, 00138 const char *); 00139 extern int finite (double); 00140 /*@}*/ 00141 00142 /* ========================================================================= */ 00143 /** @name Code Location Utility: 00144 * this are utility macros to print information about where we are. 00145 * @note For some reason __func__ don't work correctly for sun's cc in inline 00146 * functions, so we don't use in SUN architecture */ 00147 /* @{ */ 00148 #define __EG_PRINTLOCF__(F) fprintf(((F==0)?stderr:F),", in %s (%s:%d)\n",__func__,__FILE__,__LINE__) 00149 #define __EG_PRINTLOC__ __EG_PRINTLOCF__(stderr) 00150 #define __EG_PRINTLOC2F__(F) fprintf(((F==0)?stderr:F),"in %s (%s:%d)\n",__func__,__FILE__,__LINE__) 00151 #define __EG_PRINTLOC2__ __EG_PRINTLOC2F__(stderr) 00152 /* @} */ 00153 00154 #if DEBUG>=1 00155 /* ========================================================================= */ 00156 /** @brief This macro is to print error messages and to return with value one 00157 * from the current function, it also print the file and line where this 00158 * happend, but the condition is looked only if the debug level is at least L 00159 * */ 00160 #define EXITL(L,A,...) ({\ 00161 if(L<=DEBUG){\ 00162 if(A){\ 00163 fprintf(stderr,__VA_ARGS__);\ 00164 __EG_PRINTLOC__;\ 00165 exit(1);}}}) 00166 00167 /* ========================================================================= */ 00168 /** @brief This macro is to print error messages and to return with value one 00169 * from the current function, it also print the file and line where this 00170 * happend, but the condition is looked only if the debug level is at least L 00171 * */ 00172 #define TESTL(L,A,...) ({\ 00173 if(L<=DEBUG){\ 00174 if(A){\ 00175 fprintf(stderr,__VA_ARGS__);\ 00176 __EG_PRINTLOC__;\ 00177 return 1;}}}) 00178 00179 /* ========================================================================= */ 00180 /** @brief this macro check if the value of a pointer is not bellow the first 00181 * 64Kb, if so it return the given value */ 00182 #define PTRTEST(ptr,rval) {\ 00183 if(ptr) ADVTESTL(0,((size_t)(ptr)) < (1U<<16),rval, \ 00184 "%s=%p is not a valid pointer",\ 00185 #ptr, (void*)(ptr));} 00186 00187 /* ========================================================================= */ 00188 /** @brief This macro is to print error messages and to return with value one 00189 * from the current function, it also print the file and line where this 00190 * happend */ 00191 #define TESTG(A,B,...) ({\ 00192 if(A){\ 00193 fprintf(stderr,__VA_ARGS__);\ 00194 __EG_PRINTLOC__;\ 00195 goto B;}}) 00196 00197 /* ========================================================================= */ 00198 /** @brief This macro is to print error messages and to return with value one 00199 * from the current function, it also print the file and line where this 00200 * happend */ 00201 #define TEST(A,...) ({\ 00202 if(A){\ 00203 fprintf(stderr,__VA_ARGS__);\ 00204 __EG_PRINTLOC__;\ 00205 return 1;}}) 00206 00207 /* ========================================================================= */ 00208 /** @brief This macro print messages to the screen when the debug level is as 00209 * big as the first parameter, if the debug level is zero we eliminate the 00210 * code and reduce it to the empty instruction. */ 00211 #define MESSAGEF(A,F,...) ({\ 00212 if(A <= DEBUG ){\ 00213 fprintf(((F==0)?stderr:F),__VA_ARGS__);\ 00214 __EG_PRINTLOCF__(F);}}) 00215 00216 /* ========================================================================= */ 00217 /** @brief This macro print messages to the screen when the debug level is as 00218 * big as the first parameter, if the debug level is zero we eliminate the 00219 * code and reduce it to the empty instruction. */ 00220 #define MESSAGE(A,...) ({\ 00221 if(A <= DEBUG ){\ 00222 fprintf(stderr,__VA_ARGS__);\ 00223 __EG_PRINTLOC__;}}) 00224 00225 #if VERBOSE_LEVEL >= 1 00226 /* ========================================================================= */ 00227 /** @brief This macro print messages to the screen when the verbose level is as 00228 * big as the first parameter, if the verbose level is zero we eliminate the 00229 * code and reduce it to the empty instruction. */ 00230 #define OUTPUT(A,...) ({\ 00231 if(A <= VERBOSE_LEVEL ){\ 00232 fprintf(stderr,__VA_ARGS__);}}) 00233 #else 00234 #define OUTPUT(A,...) ; 00235 #endif 00236 00237 /* ========================================================================= */ 00238 /** @brief This macro print messages to the screen when the condition A is 00239 * true .if the debug level is one we don't print any warning message. if 00240 * the debug level is zero we eliminate the code and reduce it to the empty 00241 * instruction. */ 00242 #define WARNINGL(L,A,...) ({\ 00243 if((A)&&(DEBUG>=L)){\ 00244 fprintf(stderr,"WARNING: ");\ 00245 fprintf(stderr,__VA_ARGS__);\ 00246 __EG_PRINTLOC__;}}) 00247 00248 #else 00249 #define TESTL(L,A,...) ; 00250 #define EXITL(L,A,...) ; 00251 #define TEST(A,...) ; 00252 #define TESTG(A,B,...) ; 00253 #define MESSAGE(A,...) ; 00254 #define MESSAGEF(A,F,...) ; 00255 #define WARNINGL(L,A,...) ; 00256 #define PTRTEST(ptr,rval) ; 00257 #endif 00258 00259 /* ========================================================================= */ 00260 /** @brief This macro print messages to the screen when the condition A is 00261 * true. */ 00262 #define WARNING(A,...) ({if(A){\ 00263 fprintf(stderr,"WARNING: ");\ 00264 fprintf(stderr,__VA_ARGS__);\ 00265 __EG_PRINTLOC__;}}) 00266 00267 /* ========================================================================= */ 00268 /** @brief this macro test if a value is non zero, if it is it print where is 00269 * it and exit 1. The idea is to use it to check return values of functions, 00270 * and the calling function can't return a status, and then we are forced to 00271 * exit. */ 00272 #define EXITRVAL(A) ({\ 00273 if(A){\ 00274 __EG_PRINTLOC2__;\ 00275 exit(1);}}) 00276 00277 /* ========================================================================= */ 00278 /** @brief This macro is to print error messages and exit the program with 00279 * code one from the current function, it also print the file and line where 00280 * this happend */ 00281 #define EXIT(A,...) ({if(A){\ 00282 fprintf(stderr,"EXIT: ");\ 00283 fprintf(stderr,__VA_ARGS__);\ 00284 __EG_PRINTLOC__;\ 00285 exit(1);}}) 00286 00287 /* ========================================================================= */ 00288 /** @brief this macro test if a value is non zero, if it is it print where is 00289 * it and return B. The idea is to use it to check return values of functions 00290 * */ 00291 #define ADVCHECKRVAL(A,B) ({\ 00292 if(A){\ 00293 __EG_PRINTLOC2__;\ 00294 return B;}}) 00295 00296 /* ========================================================================= */ 00297 /** @brief This macro test a condition 'cond' when the debug level used at 00298 * compile time is at least 'level'. If the condition is true, it print the 00299 * message and return the 'rval' value. */ 00300 #define ADVTESTL(level,cond,rval,...) ({\ 00301 if((DEBUG>=level)&&(cond)){\ 00302 fprintf(stderr,__VA_ARGS__);\ 00303 __EG_PRINTLOC__;\ 00304 return rval;}}) 00305 00306 /* ========================================================================= */ 00307 /** @brief this macro test if a value is non zero, if it is it print where is 00308 * it and return 1. The idea is to use it to check return values of functions 00309 * */ 00310 #define CHECKRVAL(A) ({\ 00311 if(A){\ 00312 __EG_PRINTLOC2__;\ 00313 return A;}}) 00314 00315 /* ========================================================================= */ 00316 /** @brief, if a non-zero value is given as an argument, check the errno stored 00317 * in the system, print the related message, and return the non-zero given 00318 * parameter, otherwise, do nothing. 00319 * @param __value if non-zero check systems errors, and return this value 00320 * */ 00321 #define TESTERRNOIF(__value) do{\ 00322 if(__value){\ 00323 const int __EGserrno = errno;\ 00324 fprintf(stderr,"failed with errno %d, %s\n",__EGserrno, strerror(__EGserrno));\ 00325 __EG_PRINTLOC2__;\ 00326 return __value;}}while(0) 00327 /* ========================================================================= */ 00328 /** @brief this function, if the input is non zero, print a message of 00329 * function, file and line and then goto the second parameter */ 00330 #define CHECKRVALG(A,B) ({\ 00331 if(A){\ 00332 __EG_PRINTLOC2__;\ 00333 goto B;}}) 00334 00335 /* ========================================================================= */ 00336 /** @brief Define the real rand_max value of (random). In linux machines is 00337 * as RAND_MAX, but in SUN is 2^31-1 */ 00338 #if OS == LINUX 00339 #define EGRAND_MAX RAND_MAX 00340 #endif 00341 #if OS == SUN 00342 #define EGRAND_MAX ( (1LL << 31) - 1 ) 00343 #endif 00344 #ifndef EGRAND_MAX 00345 #error You have to specify the architecture, either SUN or LINUX are supported so far 00346 #endif 00347 00348 /* ========================================================================= */ 00349 /** @brief retrieve the data of type 'type' in the structure 'data' that is 00350 * located in the offset 'osN'. */ 00351 #define EGosGetData(data,osN,type) (*((type*)(((char*)data)+osN))) 00352 00353 /* ========================================================================= */ 00354 /** @brief set the data of type 'type' in the structure 'data' that is 00355 * located in the offset 'osN' to the value 'val'. */ 00356 #define EGosSetData(data,osN,type,val) (EGosGetData(data,osN,type)=val) 00357 00358 /* ========================================================================= */ 00359 /** @brief Defione copy functions, these functions 00360 * return copy of objects but with independent storage space, there are two 00361 * versions, one that require a memory pool from where to look for memory, and 00362 * another where we don't care about that.... the place from where the memory 00363 * was asked for depend on the function, se the function definition for 00364 * details. 00365 * Note that if the is no more memory available the function should call 00366 * exit(1). 00367 * This is only intended as a readibility help */ 00368 typedef void *(*EGcopy_f) (void *p); 00369 00370 /* ========================================================================= */ 00371 /** @brief Define a null copy function */ 00372 #define nullCopy ((EGcopy_f)0) 00373 00374 /* ========================================================================= */ 00375 /** @name Algorithms Return Status 00376 * Here we define some general status for algorithms, the exact meaning should 00377 * be sought in the actual algorithm definition, but the definitions here 00378 * provide a first overview of their meaning. */ 00379 /*@{*/ 00380 /** @brief the algorithm finish successfully. */ 00381 #define EG_ALGSTAT_SUCCESS 0 00382 /** @brief the algorithm could only partially finish */ 00383 #define EG_ALGSTAT_PARTIAL 1 00384 /** @brief the algorithm stop because of some numerical problem */ 00385 #define EG_ALGSTAT_NUMERROR 2 00386 /** @brief the algorithm stop because of some unforeseen error */ 00387 #define EG_ALGSTAT_ERROR 3 00388 /*@}*/ 00389 00390 /* ========================================================================= */ 00391 /** @name Mathematical Constants 00392 * Here we define some mathematical constants needed in some parts of the code 00393 * that are of general use */ 00394 /*@{*/ 00395 /** @brief definition of \f$\pi\f$ as a constant, suitable for quad-IEEE 00396 * operations. */ 00397 #define EG_M_PI 3.1415926535897932384626433832795029L 00398 /*@}*/ 00399 00400 /* ========================================================================= */ 00401 /** @} */ 00402 /* end of eg_macros.h */ 00403 #endif