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 * - 2005-12-19 00028 * - Add float128 support ussing SoftFloat. 00029 * - 2005-10-28 00030 * - Add some status definitions for algorithms. 00031 * - 2005-06-14 00032 * - Add strdup definition, just for cleanliness when compiling 00033 * - 2005-05-23 00034 * - Add EGcontainerOf 00035 * - 2005-05-03 00036 * - Add typeof definition; 00037 * - 2004-07-14 00038 * - Add GNU_MP_Z GNU_MP_F and GNU_MP_Q to the type definitions. 00039 * - 2004-07-12 00040 * - Add EGRAT_TYPE to the type definitions. 00041 * - 2004-03-17 00042 * - Add TESTG that if recives something that is nonzero print an 00043 * user message and the go to the given location. 00044 * - 2004-02-05 00045 * - Add CHECKRVALG that checks a return value, display a mesage, 00046 * and then perform a goto. 00047 * - 2003-12-01 00048 * - Add definition of a 'copy' function and its MP version. 00049 * - 2003-11-20 00050 * - Add PTRTEST that check if a pointer points to the first 64Kb of 00051 * memory internal memory. Althought such situation may happend 00052 * (if we work in kernel-related stuff), it is usually an error 00053 * when we try to access such a memory. 00054 * - 2003-09-08 00055 * - Add ADVTESTL 00056 * - 2003-07-10 00057 * - Add MESSAGEF, ADVCHECKRVAL 00058 * - 2003-07-02 00059 * - Add EGosGetData, EGosSetData, EGosGetOffset 00060 * - 2003-06-16 00061 * - Add EXITL macro 00062 * - 2003-06-06 00063 * - Add TESTL macro to test conditions but only when the debug 00064 * level is at least some value 00065 * - 2003-05-22 00066 * - Add EXITRVAL 00067 * - 2003-05-15 00068 * - Add CHECKRVAL MESSAGE and WARNING macros. 00069 * - 2003-05-08 00070 * - Add support for variadic macros for EXIT and TEST 00071 * - Define EGRAND_MAX for SUN and LINUX acordingly, this is becouse 00072 * for some reason the value of RAND_MAX in SUN is not as 00073 * specified in stdlib.h but rather 1 << 31 - 1. Still I am not 00074 * sure about the maximum value of rand() on sun... will fix that 00075 * later on to. 00076 * - Add a mesage macro, it only print if the debug level is as high 00077 * as required by the first field. Again the definition is 00078 * variadric and if the debug level is 0 we reduce the macro to 00079 * the empty instruction. 00080 * 00081 * */ 00082 /** @{*/ 00083 /** @file 00084 * */ 00085 /* ========================================================================= */ 00086 00087 #ifndef __EG_MACROS_H__ 00088 #define __EG_MACROS_H__ 00089 #include <stdlib.h> 00090 #include <stdio.h> 00091 #include "eg_config.h" 00092 #ifndef HAVE_GNU_MP 00093 #define HAVE_GNU_MP 1 00094 #endif 00095 00096 /* ========================================================================= */ 00097 /** @brief We define the GNU C extension typeof if necesary. */ 00098 #ifndef typeof 00099 #define typeof __typeof__ 00100 #endif 00101 00102 /* ========================================================================= */ 00103 /** @brief return the offset of a member inside a structure. 00104 * @param type the type of the containing structure. 00105 * @param member the name of the member that we are interested in compute the 00106 * offset. 00107 * @return the number of bytes between the member and the beginning of the 00108 * structure. */ 00109 #define EGoffsetOf(type,member) ((size_t) &((type *)0)->member) 00110 00111 /* ========================================================================= */ 00112 /** @brief given a pointer to a member of a structure, return the pointer to 00113 * the head of the structure. (idea taken from Linux Kernel). 00114 * @param ptr pointer to the member of the containing structure. 00115 * @param type name type of the containing structure. 00116 * @param member name of the given member in the containing structure. 00117 * @return pointer to the containing structure. 00118 * */ 00119 #define EGcontainerOf(ptr,type,member) ({\ 00120 typeof(((type *)0)->member) *const __EGcOf_ptr = (ptr);\ 00121 (type *)( (char*)__EGcOf_ptr - EGoffsetOf(type,member));}) 00122 00123 /* ========================================================================= */ 00124 /** @name External C-library functions: 00125 * Here we define some C-library functions that for some weird reason can't 00126 * be found at compile time but are present at linking time */ 00127 /*@{*/ 00128 extern void srandom (unsigned int); 00129 extern long random (void); 00130 extern double drand48 (void); 00131 extern long lrand48 (void); 00132 extern char *optarg; 00133 extern int getopt (int, 00134 char *const *, 00135 const char *); 00136 extern int finite (double); 00137 /*@}*/ 00138 00139 /* ========================================================================= */ 00140 /** @name Code Location Utility: 00141 * this are utility macros to print information about where we are. 00142 * @note For some reason __func__ don't work correctly for sun's cc in inline 00143 * functions, so we don't use in SUN architecture */ 00144 /* @{ */ 00145 #define __EG_PRINTLOCF__(F) fprintf(((F==0)?stderr:F),", in %s (%s:%d)\n",__func__,__FILE__,__LINE__) 00146 #define __EG_PRINTLOC__ __EG_PRINTLOCF__(stderr) 00147 #define __EG_PRINTLOC2F__(F) fprintf(((F==0)?stderr:F),"in %s (%s:%d)\n",__func__,__FILE__,__LINE__) 00148 #define __EG_PRINTLOC2__ __EG_PRINTLOC2F__(stderr) 00149 /* @} */ 00150 00151 #if DEBUG>=1 00152 /* ========================================================================= */ 00153 /** @brief This macro is to print error messages and to return with value one 00154 * from the current function, it also print the file and line where this 00155 * happend, but the condition is looked only if the debug level is at least L 00156 * */ 00157 #define EXITL(L,A,...) ({\ 00158 if(L<=DEBUG){\ 00159 if(A){\ 00160 fprintf(stderr,__VA_ARGS__);\ 00161 __EG_PRINTLOC__;\ 00162 exit(1);}}}) 00163 00164 /* ========================================================================= */ 00165 /** @brief This macro is to print error messages and to return with value one 00166 * from the current function, it also print the file and line where this 00167 * happend, but the condition is looked only if the debug level is at least L 00168 * */ 00169 #define TESTL(L,A,...) ({\ 00170 if(L<=DEBUG){\ 00171 if(A){\ 00172 fprintf(stderr,__VA_ARGS__);\ 00173 __EG_PRINTLOC__;\ 00174 return 1;}}}) 00175 00176 /* ========================================================================= */ 00177 /** @brief this macro check if the value of a pointer is not bellow the first 00178 * 64Kb, if so it return the given value */ 00179 #define PTRTEST(ptr,rval) {\ 00180 if(ptr) ADVTESTL(0,((size_t)(ptr)) < (1U<<16),rval, \ 00181 "%s=%p is not a valid pointer",\ 00182 #ptr, (void*)(ptr));} 00183 00184 /* ========================================================================= */ 00185 /** @brief This macro is to print error messages and to return with value one 00186 * from the current function, it also print the file and line where this 00187 * happend */ 00188 #define TESTG(A,B,...) ({\ 00189 if(A){\ 00190 fprintf(stderr,__VA_ARGS__);\ 00191 __EG_PRINTLOC__;\ 00192 goto B;}}) 00193 00194 /* ========================================================================= */ 00195 /** @brief This macro is to print error messages and to return with value one 00196 * from the current function, it also print the file and line where this 00197 * happend */ 00198 #define TEST(A,...) ({\ 00199 if(A){\ 00200 fprintf(stderr,__VA_ARGS__);\ 00201 __EG_PRINTLOC__;\ 00202 return 1;}}) 00203 00204 /* ========================================================================= */ 00205 /** @brief This macro print messages to the screen when the debug level is as 00206 * big as the first parameter, if the debug level is zero we eliminate the 00207 * code and reduce it to the empty instruction. */ 00208 #define MESSAGEF(A,F,...) ({\ 00209 if(A <= DEBUG ){\ 00210 fprintf(((F==0)?stderr:F),__VA_ARGS__);\ 00211 __EG_PRINTLOCF__(F);}}) 00212 00213 /* ========================================================================= */ 00214 /** @brief This macro print messages to the screen when the debug level is as 00215 * big as the first parameter, if the debug level is zero we eliminate the 00216 * code and reduce it to the empty instruction. */ 00217 #define MESSAGE(A,...) ({\ 00218 if(A <= DEBUG ){\ 00219 fprintf(stderr,__VA_ARGS__);\ 00220 __EG_PRINTLOC__;}}) 00221 00222 #if VERBOSE_LEVEL >= 1 00223 /* ========================================================================= */ 00224 /** @brief This macro print messages to the screen when the verbose level is as 00225 * big as the first parameter, if the verbose level is zero we eliminate the 00226 * code and reduce it to the empty instruction. */ 00227 #define OUTPUT(A,...) ({\ 00228 if(A <= VERBOSE_LEVEL ){\ 00229 fprintf(stderr,__VA_ARGS__);}}) 00230 #else 00231 #define OUTPUT(A,...) ; 00232 #endif 00233 00234 /* ========================================================================= */ 00235 /** @brief This macro print messages to the screen when the condition A is 00236 * true .if the debug level is one we don't print any warning message. if 00237 * the debug level is zero we eliminate the code and reduce it to the empty 00238 * instruction. */ 00239 #define WARNINGL(L,A,...) ({\ 00240 if((A)&&(DEBUG>=L)){\ 00241 fprintf(stderr,"WARNING: ");\ 00242 fprintf(stderr,__VA_ARGS__);\ 00243 __EG_PRINTLOC__;}}) 00244 00245 #else 00246 #define TESTL(L,A,...) ; 00247 #define EXITL(L,A,...) ; 00248 #define TEST(A,...) ; 00249 #define TESTG(A,B,...) ; 00250 #define MESSAGE(A,...) ; 00251 #define MESSAGEF(A,F,...) ; 00252 #define WARNINGL(L,A,...) ; 00253 #define PTRTEST(ptr,rval) ; 00254 #endif 00255 00256 /* ========================================================================= */ 00257 /** @brief This macro print messages to the screen when the condition A is 00258 * true. */ 00259 #define WARNING(A,...) ({if(A){\ 00260 fprintf(stderr,"WARNING: ");\ 00261 fprintf(stderr,__VA_ARGS__);\ 00262 __EG_PRINTLOC__;}}) 00263 00264 /* ========================================================================= */ 00265 /** @brief this macro test if a value is non zero, if it is it print where is 00266 * it and exit 1. The idea is to use it to check return values of functions, 00267 * and the calling function can't return a status, and then we are forced to 00268 * exit. */ 00269 #define EXITRVAL(A) ({\ 00270 if(A){\ 00271 __EG_PRINTLOC2__;\ 00272 exit(1);}}) 00273 00274 /* ========================================================================= */ 00275 /** @brief This macro is to print error messages and exit the program with 00276 * code one from the current function, it also print the file and line where 00277 * this happend */ 00278 #define EXIT(A,...) ({if(A){\ 00279 fprintf(stderr,__VA_ARGS__);\ 00280 __EG_PRINTLOC__;\ 00281 exit(1);}}) 00282 00283 /* ========================================================================= */ 00284 /** @brief this macro test if a value is non zero, if it is it print where is 00285 * it and return B. The idea is to use it to check return values of functions 00286 * */ 00287 #define ADVCHECKRVAL(A,B) ({\ 00288 if(A){\ 00289 __EG_PRINTLOC2__;\ 00290 return B;}}) 00291 00292 /* ========================================================================= */ 00293 /** @brief This macro test a condition 'cond' when the debug level used at 00294 * compile time is at least 'level'. If the condition is true, it print the 00295 * message and return the 'rval' value. */ 00296 #define ADVTESTL(level,cond,rval,...) ({\ 00297 if((DEBUG>=level)&&(cond)){\ 00298 fprintf(stderr,__VA_ARGS__);\ 00299 __EG_PRINTLOC__;\ 00300 return rval;}}) 00301 00302 /* ========================================================================= */ 00303 /** @brief this macro test if a value is non zero, if it is it print where is 00304 * it and return 1. The idea is to use it to check return values of functions 00305 * */ 00306 #define CHECKRVAL(A) ({\ 00307 if(A){\ 00308 __EG_PRINTLOC2__;\ 00309 return A;}}) 00310 00311 /* ========================================================================= */ 00312 /** @brief this function, if the input is non zero, print a message of 00313 * function, file and line and then goto the second parameter */ 00314 #define CHECKRVALG(A,B) ({\ 00315 if(A){\ 00316 __EG_PRINTLOC2__;\ 00317 goto B;}}) 00318 00319 /* ========================================================================= */ 00320 /** @brief Define the real rand_max value of (random). In linux machines is 00321 * as RAND_MAX, but in SUN is 2^31-1 */ 00322 #if OS == LINUX 00323 #define EGRAND_MAX RAND_MAX 00324 #endif 00325 #if OS == SUN 00326 #define EGRAND_MAX ( (1LL << 31) - 1 ) 00327 #endif 00328 #ifndef EGRAND_MAX 00329 #error You have to specify the architecture, either SUN or LINUX are supported so far 00330 #endif 00331 00332 /* ========================================================================= */ 00333 /** @brief retrieve the data of type 'type' in the structure 'data' that is 00334 * located in the offset 'osN'. */ 00335 #define EGosGetData(data,osN,type) (*((type*)(((char*)data)+osN))) 00336 00337 /* ========================================================================= */ 00338 /** @brief set the data of type 'type' in the structure 'data' that is 00339 * located in the offset 'osN' to the value 'val'. */ 00340 #define EGosSetData(data,osN,type,val) (EGosGetData(data,osN,type)=val) 00341 00342 /* ========================================================================= */ 00343 /** @brief This is a redifinition of an old function to the newer 00344 * implementation provided by #EGoffsetOf. It return the offset of a member 00345 * inside a structure. */ 00346 #define EGosGetOffset(my_struct, my_member) EGoffsetOf(my_struct,my_member) 00347 00348 /* ========================================================================= */ 00349 /** @name Number Types Definitions: 00350 * Define (as its name suggest) an internal identifier for the given 00351 * type. this definitions are provided to select different types of data at 00352 * compile time, thus allowing us to provide limited template support. */ 00353 /*@{*/ 00354 /** C double type. */ 00355 #define DBL_TYPE 0 00356 /** C float type. */ 00357 #define FLT_TYPE 1 00358 /** C int type. */ 00359 #define INT_TYPE 2 00360 /** EGlib #EGfp10_t type, this is an implementation of fixed precision 00361 * arithmetic with 10 bits for fractional representation. */ 00362 #define FP10_TYPE 3 00363 /** EGlib #EGfp20_t type, this is an implementation of fixed precision 00364 * arithmetic with 20 bits for fractional representation. */ 00365 #define FP20_TYPE 4 00366 /** EGlib #EGfp28_t type, this is an implementation of fixed precision 00367 * arithmetic with 28 bits for fractional representation. */ 00368 #define FP28_TYPE 5 00369 /** EGlib #EGfp25_t type, this is an implementation of fixed precision 00370 * arithmetic with 25 bits for fractional representation. */ 00371 #define FP25_TYPE 6 00372 #if HAVE_GNU_MP 00373 /** GNU_MP library mpz_t type */ 00374 #define GNU_MP_Z 8 00375 /** GNU_MP library mpq_t type */ 00376 #define GNU_MP_Q 9 00377 /** GNU_MP library mpf_t type */ 00378 #define GNU_MP_F 10 00379 #endif 00380 /** C long double type */ 00381 #define LDBL_TYPE 11 00382 /** C long long int type */ 00383 #define LLINT_TYPE 12 00384 /** SoftFloat 128-bit floating point numbner */ 00385 #define FLOAT128_TYPE 13 00386 /*@}*/ 00387 00388 /* ========================================================================= */ 00389 /** @brief Defione copy functions, these functions 00390 * return copy of objects but with independent storage space, there are two 00391 * versions, one that require a memory pool from where to look for memory, and 00392 * another where we don't care about that.... the place from where the memory 00393 * was asked for depend on the function, se the function definition for 00394 * details. 00395 * Note that if the is no more memory available the function should call 00396 * exit(1). 00397 * This is only intended as a readibility help */ 00398 typedef void *(*EGcopy_f) (void *p); 00399 00400 00401 /* ========================================================================= */ 00402 /** @brief Define a null copy function */ 00403 #define nullCopy ((EGcopy_f)0) 00404 00405 /* ========================================================================= */ 00406 /** @name Algorithms Return Status 00407 * Here we define some general status for algorithms, the exact meaning should 00408 * be sought in the actual algorithm definition, but the definitions here 00409 * provide a first overview of their meaning. */ 00410 /*@{*/ 00411 /** @brief the algorithm finish successfully. */ 00412 #define EG_ALGSTAT_SUCCESS 0 00413 /** @brief the algorithm could only partially finish */ 00414 #define EG_ALGSTAT_PARTIAL 1 00415 /** @brief the algorithm stop because of some numerical problem */ 00416 #define EG_ALGSTAT_NUMERROR 2 00417 /** @brief the algorithm stop because of some unforeseen error */ 00418 #define EG_ALGSTAT_ERROR 3 00419 /*@}*/ 00420 /* ========================================================================= */ 00421 /** @} */ 00422 /* end of eg_macros.h */ 00423 #endif
1.4.5