summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/warnings.h
blob: 1d9f4b7d749beadf1dc212eb517d00ace5a13d29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 */

#ifndef __included_warnings_h__
#define __included_warnings_h__

/* Macros to check compiler version */
#if defined(__GNUC__)
#define COMPILER_VERSION_GTE(major, minor) \
  (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
#elif defined(__clang__)
#define COMPILER_VERSION_GTE(major, minor) \
  (__clang_major__ > (major) ||            \
   (__clang_major__ == (major) && __clang_minor__ >= (minor)))
#else /* disable all warning customization for all other compilers */
#define COMPILER_VERSION_GTE(maj, min) 0
#endif

/* '#' needs to preceed a macro parameter */
#define WARN_TOSTR(x) #x

/*
 * Macros to toggle off/on warnings
 *
 * Start by silencing pragma warnings so that we can explicitly silence
 * a warning introduced on some compiler version and not get a warning on older
 * versions of that same compiler.
 *
 * gcc corresponding warning is "Wpargma"
 * clang corresponding warning is "Wunknown-warning-option"
 *
 * For example, Wtautological-compare is introduced in gcc-6 and this would
 * trigger a Wpargma warning on gcc-5.
 *
 * Example usage to disable -Wtautological-compare warning:
 *   WARN_OFF(tautological-compare)
 *   if (...) {
 *   WARN_ON(tautological-compare)
 *     ; // conditional code
 *   }
 */
#if defined(__GNUC__) && COMPILER_VERSION_GTE(4, 6)
/*
 * GCC option to locally ignore warning was introduced in gcc-4.6
 * gcc.gnu.org/gcc-4.6/changes.html
 */
#define WARN_PRAGMA(x) _Pragma (WARN_TOSTR (GCC diagnostic x))
#define WARN_OFF(x)                                    \
  WARN_PRAGMA (push) WARN_PRAGMA (ignored "-Wpragmas") \
  WARN_PRAGMA (push) WARN_PRAGMA (ignored WARN_TOSTR (-W##x))
#define WARN_ON(x)  \
  WARN_PRAGMA (pop) \
  WARN_PRAGMA (pop)

#elif defined(__clang__) && COMPILER_VERSION_GTE(3, 3)
/*
 * clang option to locally ignore warning was introduced in clang-3.3
 * releases.llvm.org/3.3/tools/clang/docs/UsersManual.html#controlling-diagnostics-via-pragmas
 */
#define WARN_PRAGMA(x) _Pragma (WARN_TOSTR (clang diagnostic x))
#define WARN_OFF(x)                                                   \
  WARN_PRAGMA (push) WARN_PRAGMA (ignored "-Wunknown-warning-option") \
  WARN_PRAGMA (push) WARN_PRAGMA (ignored WARN_TOSTR (-W##x))
#define WARN_ON(x)  \
  WARN_PRAGMA (pop) \
  WARN_PRAGMA (pop)
#else
/* Ignore WARN_* instruction for all other compilers */
#define WARN_OFF(x)
#define WARN_ON(x)
#endif

/*
 * Clang supports a wider range of warnings than gcc.
 * Use those specific macros for the warnings that are only supported by clang
 */
#ifdef __clang__
#define WARN_OFF_CLANG(x) WARN_OFF (x)
#define WARN_ON_CLANG(x) WARN_ON (x)
#else
#define WARN_OFF_CLANG(x)
#define WARN_ON_CLANG(x)
#endif

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
#endif /* __included_warnings_h__ */
return {'ip6': self.ip_addr.packed} else: return {'ip4': self.ip_addr.packed} @property def version(self): return self.ip_addr.version @property def address(self): return self.addr @property def length(self): return self.ip_addr.max_prefixlen @property def bytes(self): return self.ip_addr.packed def __eq__(self, other): if isinstance(other, self.__class__): return self.ip_addr == other.ip_addr elif hasattr(other, "ip4") and hasattr(other, "ip6"): # vl_api_address_union_t if 4 == self.version: return self.ip_addr.packed == other.ip4 else: return self.ip_addr.packed == other.ip6 else: _log.error("Comparing VppIpAddressUnions:%s" " with incomparable type: %s", self, other) return NotImplemented class VppIpAddress(): def __init__(self, addr): self.addr = VppIpAddressUnion(addr) def encode(self): if self.addr.version == 6: return { 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6, 'un': self.addr.encode() } else: return { 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4, 'un': self.addr.encode() } def __eq__(self, other): if isinstance(other, self.__class__): return self.addr == other.addr elif hasattr(other, "af") and hasattr(other, "un"): # a vp_api_address_t if 4 == self.version: return other.af == \ VppEnum.vl_api_address_family_t.ADDRESS_IP4 and \ other.un == self.addr else: return other.af == \ VppEnum.vl_api_address_family_t.ADDRESS_IP6 and \ other.un == self.addr else: _log.error( "Comparing VppIpAddress:<%s> %s with incomparable " "type: <%s> %s", self.__class__.__name__, self, other.__class__.__name__, other) return NotImplemented def __ne__(self, other): return not (self == other) def __str__(self): return self.address @property def bytes(self): return self.addr.bytes @property def address(self): return self.addr.address @property def length(self): return self.addr.length @property def version(self): return self.addr.version @property def is_ip6(self): return (self.version == 6) @property def af(self): if self.version == 6: return AF_INET6 else: return AF_INET @property def dpo_proto(self): if self.version == 6: return DpoProto.DPO_PROTO_IP6 else: return DpoProto.DPO_PROTO_IP4 class VppIpPrefix(): def __init__(self, addr, len): self.addr = VppIpAddress(addr) self.len = len def encode(self): return {'address': self.addr.encode(), 'address_length': self.len} @property def address(self): return self.addr.address @property def bytes(self): return self.addr.bytes @property def length(self): return self.len @property def is_ip6(self): return self.addr.is_ip6 def __str__(self): return "%s/%d" % (self.address, self.length) def __eq__(self, other): if isinstance(other, self.__class__): return (self.len == other.len and self.addr == other.addr) elif hasattr(other, "address") and hasattr(other, "address_length"): # vl_api_prefix_t return self.len == other.address_length and \ self.addr == other.address else: _log.error( "Comparing VppIpPrefix:%s with incomparable type: %s" % (self, other)) return NotImplemented class VppIpMPrefix(): def __init__(self, saddr, gaddr, len): self.saddr = saddr self.gaddr = gaddr self.len = len self.ip_saddr = ip_address(text_type(self.saddr)) self.ip_gaddr = ip_address(text_type(self.gaddr)) if self.ip_saddr.version != self.ip_gaddr.version: raise ValueError('Source and group addresses must be of the ' 'same address family.') def encode(self): if 6 == self.ip_saddr.version: prefix = { 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP6, 'grp_address': {'ip6': self.ip_gaddr.packed}, 'src_address': {'ip6': self.ip_saddr.packed}, 'grp_address_length': self.len, } else: prefix = { 'af': VppEnum.vl_api_address_family_t.ADDRESS_IP4, 'grp_address': {'ip4': self.ip_gaddr.packed}, 'src_address': {'ip4': self.ip_saddr.packed}, 'grp_address_length': self.len, } return prefix