eg_macros.h

Go to the documentation of this file.
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

Generated on Mon Jan 30 08:48:53 2006 for EGlib by  doxygen 1.4.5