• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

/home/pvrabec/project/openscap/openscap-0.6.3/src/common/assume.h

00001 
00002 /*
00003  * Copyright 2009 Red Hat Inc., Durham, North Carolina.
00004  * All Rights Reserved.
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  * Authors:
00021  *       Lukas Kuklinek <lkuklinek@redhat.com>
00022  */
00023 
00024 #pragma once
00025 #ifndef ASSUME_H
00026 #define ASSUME_H
00027 
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include "util.h"
00031 
00032 /*
00033  * Note: the term "terminate" used in the following text means a call to abort()
00034  *       in the case the code was compiled without NDEBUG defined. The retval
00035  *       argument is ignored in that case. In the other case (NDEBUG is defined)
00036  *       terminate means that `return (retval)' is used instead of aborting the
00037  *       program. This is because we are in a library and taking down a program
00038  *       from inside a library function isn't safe.
00039  *         Unless ASSUME_VERBOSE is defined during compilation time, assume won't
00040  *       emit any messages to stderr. In debugging mode (i.e. when NDEBUG is
00041  *       undefined) the error message is always written to stderr.
00042  *
00043  * Usage:
00044  *
00045  * 1. assume(expr, retval)
00046  *
00047  *    Check whether expr is true, terminate if not.
00048  *
00049  * 2. assume(expr, retval, f_branch)
00050  *    
00051  *    Check whether expr is true, execute f_branch if not and terminate. The break
00052  *    statement can be used to skip the termination.
00053  *   
00054  * 3. assume(expr, retval, f_branch, t_branch)
00055  *
00056  *    Check whether expr is true, execute f_branch if not and terminate. If expr
00057  *    is true, then execute t_branch.
00058  *    
00059  */
00060 
00061 #define __LB(l, ...) l
00062 #define __RB(l, ...) __VA_ARGS__
00063 #define __emitmsg_fp stderr
00064 
00065 /*
00066  * == Implementation note #1 ==
00067  * We use ftrylockfile here because it's better to drop the message than to
00068  * cause a deadlock.
00069  */
00070 #define __atomic_emitmsg(...)                           \
00071         do {                                            \
00072                 if (ftrylockfile(__emitmsg_fp) == 0) {  \
00073                         fprintf (stderr, __VA_ARGS__);  \
00074                         funlockfile(__emitmsg_fp);      \
00075                 }                                       \
00076         } while (0)
00077 
00078 #ifndef NDEBUG
00079 # define __terminate(retval) abort()
00080 # define __emitmsg(...) __atomic_emitmsg (__VA_ARGS__)
00081 #else
00082 # define __terminate(retval) return(retval)
00083 # ifdef ASSUME_VERBOSE
00084 #  define __emitmsg(...) __atomic_emitmsg (__VA_ARGS__)
00085 # else
00086 #  define __emitmsg(...) while(0)
00087 # endif /* ASSUME_VERBOSE */
00088 #endif /* NDEBUG */
00089 
00090 #define __assume(expr, exprstr, retval, ...)                            \
00091         do {                                                            \
00092                 int OSCAP_CONCAT(__cont, __LINE__) = 1;                        \
00093                 if (!(expr)) {                                          \
00094                         __emitmsg ("%s:%d (%s): Assumption `%s' not fulfilled!\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, exprstr); \
00095                         do {__LB(__VA_ARGS__)} while((OSCAP_CONCAT(__cont, __LINE__) = 0)); \
00096                         if (OSCAP_CONCAT(__cont, __LINE__) == 0) __terminate(retval); \
00097                 } else {                                                \
00098                         do {__RB(__VA_ARGS__)} while(0);                \
00099                 }                                                       \
00100         } while (0)
00101 
00102 #if defined(__GNUC__)
00103 # define assume(expr, retval, ...) __assume(__builtin_expect(expr, 1), #expr, retval, __VA_ARGS__)
00104 #else
00105 # define assume(expr, retval, ...) __assume(expr, #expr, retval, __VA_ARGS__)
00106 #endif
00107 
00111 #define assume_r(...) assume(__VA_ARGS__)
00112 
00116 #ifndef NDEBUG
00117 # define assume_d(...) assume(__VA_ARGS__)
00118 #else
00119 # define assume_d(...) while(0)
00120 #endif
00121 
00122 #endif /* ASSUME_H */

Generated on Tue Sep 14 2010 for Open SCAP Library by  doxygen 1.7.1