xorp

utility.h

00001 /* -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- */
00002 /* vim:set sts=4 ts=8: */
00003 
00004 /*
00005  * Copyright (c) 2001-2011 XORP, Inc and Others
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU Lesser General Public License, Version
00009  * 2.1, June 1999 as published by the Free Software Foundation.
00010  * Redistribution and/or modification of this program under the terms of
00011  * any other version of the GNU Lesser General Public License is not
00012  * permitted.
00013  * 
00014  * This program is distributed in the hope that it will be useful, but
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00017  * see the GNU Lesser General Public License, Version 2.1, a copy of
00018  * which can be found in the XORP LICENSE.lgpl file.
00019  * 
00020  * XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00021  * http://xorp.net
00022  */
00023 
00024 #ifndef __LIBXORP_UTILITY_H__
00025 #define __LIBXORP_UTILITY_H__
00026 
00027 /*
00028  * Compile time assertion.
00029  */
00030 #ifndef x_static_assert
00031 // +0 is to work around clang bug.
00032 #define x_static_assert(a) switch ((a) + 0) case 0: case ((a) + 0):
00033 #endif /* x_static_assert */
00034 
00035 /*
00036  * A macro to avoid compilation warnings about unused functions arguments.
00037  * XXX: this should be used only in C. In C++ just remove the argument name
00038  * in the function definition.
00039  */
00040 #ifndef UNUSED
00041 #define UNUSED(var) x_static_assert(sizeof(var) != 0)
00042 #endif /* UNUSED */
00043 
00044 #ifdef __cplusplus
00045 #define cstring(s) (s).str().c_str()
00046 #endif
00047 
00048 /*
00049  * XORP code uses typedefs (e.g. uint32_t, int32_t) rather than using
00050  * the base types, because the 'C' language allows a compiler to use a
00051  * natural size for base type. The XORP code is internally consistent
00052  * in this usage, one problem arises with format strings in printf
00053  * style functions.
00054  *
00055  * In order to print a size_t or uint32_t with "%u" it is necessary to
00056  * cast to an unsigned int. On Mac OS X a size_t is not an unsigned
00057  * int. On windows uint32_t is not an unsigned int.
00058  *
00059  * In order to print a int32_t with a "%d" it is necessary to cast to
00060  * a signed int. On windows int32_t is not a signed int.
00061  *
00062  * The two convenience macros are provided to perform the cast.
00063  */
00064 #ifdef __cplusplus
00065 #define XORP_UINT_CAST(x)   static_cast<unsigned int>(x)
00066 #define XORP_INT_CAST(x)    static_cast<int>(x)
00067 #else
00068 #define XORP_UINT_CAST(x)   (unsigned int)(x)
00069 #define XORP_INT_CAST(x)    (int)(x)
00070 #endif
00071 
00072 /*
00073  * On some architectures casting a "(struct sockaddr *)" pointer to
00074  * "(struct sockaddr_in *)" or "(struct sockaddr_in6 *)" pointer generates
00075  * a warning like:
00076  *     warning: cast from 'sockaddr*' to 'sockaddr_in*' increases required
00077  *     alignment of target type
00078  *
00079  * In general such casting shouldn't create any alignment issues and
00080  * shouldn't generate such warning.
00081  * To get around the problem we use the help of a "void" pointer.
00082  *
00083  * If the casting actually creates an alignment problem, then we need
00084  * to copy the "struct sockaddr" content to "struct sockaddr_in" or
00085  * "struct sockaddr_in6" placeholder.
00086  * Doing this (without using local static storage) might requite changing
00087  * the semantics hence we don't provide the implementation.
00088  */
00089 #ifdef __cplusplus
00090 inline const struct sockaddr_in *
00091 sockaddr2sockaddr_in(const struct sockaddr* sa)
00092 {
00093     const void* v = sa;
00094     return (reinterpret_cast<const struct sockaddr_in*>(v));
00095 }
00096 
00097 inline struct sockaddr_in *
00098 sockaddr2sockaddr_in(struct sockaddr* sa)
00099 {
00100     void* v = sa;
00101     return (reinterpret_cast<struct sockaddr_in*>(v));
00102 }
00103 
00104 inline const struct sockaddr_in6 *
00105 sockaddr2sockaddr_in6(const struct sockaddr* sa)
00106 {
00107     const void* v = sa;
00108     return (reinterpret_cast<const struct sockaddr_in6*>(v));
00109 }
00110 
00111 inline struct sockaddr_in6 *
00112 sockaddr2sockaddr_in6(struct sockaddr* sa)
00113 {
00114     void* v = sa;
00115     return (reinterpret_cast<struct sockaddr_in6*>(v));
00116 }
00117 
00118 inline const struct sockaddr *
00119 sockaddr_storage2sockaddr(const struct sockaddr_storage* ss)
00120 {
00121     const void* v = ss;
00122     return (reinterpret_cast<const struct sockaddr*>(v));
00123 }
00124 
00125 inline struct sockaddr *
00126 sockaddr_storage2sockaddr(struct sockaddr_storage* ss)
00127 {
00128     void* v = ss;
00129     return (reinterpret_cast<struct sockaddr*>(v));
00130 }
00131 
00132 #endif /* __cplusplus */
00133 
00134 #define ADD_POINTER(pointer, size, type)                \
00135     ((type)(void *)(((uint8_t *)(pointer)) + (size)))
00136 
00137 /*
00138  * Micro-optimization: byte ordering fix for constants.  htonl uses
00139  * CPU instructions, whereas the macro below can be handled by the
00140  * compiler front-end for literal values.
00141  */
00142 #if __BYTE_ORDER == __BIG_ENDIAN
00143 #  define htonl_literal(x) (x)
00144 #elif __BYTE_ORDER == __LITTLE_ENDIAN
00145 #  define htonl_literal(x)                            \
00146         ((((x) & 0x000000ffU) << 24) | (((x) & 0x0000ff00U) << 8) |   \
00147          (((x) & 0x00ff0000U) >> 8) | (((x) & 0xff000000U) >> 24))
00148 #else
00149 #  error "Endian detection is broken."
00150 #endif
00151 
00152 /*
00153  * Various ctype(3) wrappers that work properly even if the value of the int
00154  * argument is not representable as an unsigned char and doesn't have the
00155  * value of EOF.
00156  */
00157 #ifdef __cplusplus
00158 extern "C" {
00159 #endif
00160 
00161 extern int xorp_isalnum(int c);
00162 extern int xorp_isalpha(int c);
00163 /*
00164  * TODO: for now comment-out xorp_isblank(), because isblank(3) is introduced
00165  * with ISO C99, and may not always be available on the system.
00166  */
00167 /* extern int xorp_isblank(int c); */
00168 extern int xorp_iscntrl(int c);
00169 extern int xorp_isdigit(int c);
00170 extern int xorp_isgraph(int c);
00171 extern int xorp_islower(int c);
00172 extern int xorp_isprint(int c);
00173 extern int xorp_ispunct(int c);
00174 extern int xorp_isspace(int c);
00175 extern int xorp_isupper(int c);
00176 extern int xorp_isxdigit(int c);
00177 extern int xorp_tolower(int c);
00178 extern int xorp_toupper(int c);
00179 
00180 /*
00181  * A strptime(3) wrapper that uses a local implementation of strptime(3)
00182  * if the operating system doesn't have one. Note that the particular
00183  * implementation is inside file "libxorp/strptime.c".
00184  */
00185 extern char *xorp_strptime(const char *buf, const char *fmt, struct tm *tm);
00186 
00187 /*
00188  * Function to return C-string representation of a boolean: "true" of "false".
00189  */
00190 extern const char *bool_c_str(int v);
00191 
00192 #ifdef __cplusplus
00193 }
00194 #endif
00195 
00196 #endif /* __LIBXORP_UTILITY_H__ */
 All Classes Namespaces Functions Variables Typedefs Enumerations