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  * - 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

Generated on Wed Nov 21 09:38:13 2007 for MTgomory by  doxygen 1.4.6