1 1.1 christos /* 2 1.1 christos * Copyright (c) 2023-2024 Apple Inc. All rights reserved. 3 1.1 christos * 4 1.1 christos * Licensed under the Apache License, Version 2.0 (the "License"); 5 1.1 christos * you may not use this file except in compliance with the License. 6 1.1 christos * You may obtain a copy of the License at 7 1.1 christos * 8 1.1 christos * https://www.apache.org/licenses/LICENSE-2.0 9 1.1 christos * 10 1.1 christos * Unless required by applicable law or agreed to in writing, software 11 1.1 christos * distributed under the License is distributed on an "AS IS" BASIS, 12 1.1 christos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 1.1 christos * See the License for the specific language governing permissions and 14 1.1 christos * limitations under the License. 15 1.1 christos */ 16 1.1 christos 17 1.1 christos #ifndef MDNS_GENERAL_H 18 1.1 christos #define MDNS_GENERAL_H 19 1.1 christos 20 1.1 christos /*! 21 1.1 christos * @brief 22 1.1 christos * Evaluates to non-zero if compiling for a particular platform. 23 1.1 christos * 24 1.1 christos * @param PLATFORM_NAME 25 1.1 christos * The name of the platform, e.g., APPLE. 26 1.1 christos */ 27 1.1 christos #define MDNS_PLATFORM(PLATFORM_NAME) MDNS_PLATFORM_PRIVATE_DEFINITION_ ## PLATFORM_NAME () 28 1.1 christos 29 1.1 christos /*! 30 1.1 christos * @brief 31 1.1 christos * Evaluates to non-zero if compiling for Apple OSes. 32 1.1 christos * 33 1.1 christos * @discussion 34 1.1 christos * `__APPLE__` is defined when compiling for Apple, see 35 1.1 christos * <https://developer.apple.com/library/archive/documentation/Porting/Conceptual/PortingUnix/compiling/compiling.html>. 36 1.1 christos */ 37 1.1 christos #if defined(__APPLE__) && __APPLE__ 38 1.1 christos #define MDNS_PLATFORM_PRIVATE_DEFINITION_APPLE() 1 39 1.1 christos #else 40 1.1 christos #define MDNS_PLATFORM_PRIVATE_DEFINITION_APPLE() 0 41 1.1 christos #endif 42 1.1 christos 43 1.1 christos #if MDNS_PLATFORM(APPLE) 44 1.1 christos #include <TargetConditionals.h> 45 1.1 christos #endif 46 1.1 christos 47 1.1 christos /*! 48 1.1 christos * @brief 49 1.1 christos * Evaluates to non-zero if compiling for a particular OS. 50 1.1 christos * 51 1.1 christos * @param OS_NAME 52 1.1 christos * The name of the OS, e.g., macOS, iOS, etc. 53 1.1 christos */ 54 1.1 christos #define MDNS_OS(OS_NAME) MDNS_OS_PRIVATE_DEFINITION_ ## OS_NAME () 55 1.1 christos 56 1.1 christos /*! 57 1.1 christos * @brief 58 1.1 christos * Evaluates to non-zero if compiling for macOS. 59 1.1 christos * 60 1.1 christos * @discussion 61 1.1 christos * Use `MDNS_OS(macOS)` instead of using this macro directly. 62 1.1 christos */ 63 1.1 christos #if defined(TARGET_OS_OSX) && TARGET_OS_OSX 64 1.1 christos #define MDNS_OS_PRIVATE_DEFINITION_macOS() 1 65 1.1 christos #else 66 1.1 christos #define MDNS_OS_PRIVATE_DEFINITION_macOS() 0 67 1.1 christos #endif 68 1.1 christos 69 1.1 christos /*! 70 1.1 christos * @brief 71 1.1 christos * Evaluates to non-zero if compiling for iOS. 72 1.1 christos * 73 1.1 christos * @discussion 74 1.1 christos * Use `MDNS_OS(iOS)` instead of using this macro directly. 75 1.1 christos */ 76 1.1 christos #if defined(TARGET_OS_IOS) && TARGET_OS_IOS 77 1.1 christos #define MDNS_OS_PRIVATE_DEFINITION_iOS() 1 78 1.1 christos #else 79 1.1 christos #define MDNS_OS_PRIVATE_DEFINITION_iOS() 0 80 1.1 christos #endif 81 1.1 christos 82 1.1 christos /*! 83 1.1 christos * @brief 84 1.1 christos * Evaluates to non-zero if compiling for watchOS. 85 1.1 christos * 86 1.1 christos * @discussion 87 1.1 christos * Use `MDNS_OS(watchOS)` instead of using this macro directly. 88 1.1 christos */ 89 1.1 christos #if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH 90 1.1 christos #define MDNS_OS_PRIVATE_DEFINITION_watchOS() 1 91 1.1 christos #else 92 1.1 christos #define MDNS_OS_PRIVATE_DEFINITION_watchOS() 0 93 1.1 christos #endif 94 1.1 christos 95 1.1 christos /*! 96 1.1 christos * @brief 97 1.1 christos * Evaluates to non-zero if compiling for tvOS. 98 1.1 christos * 99 1.1 christos * @discussion 100 1.1 christos * Use `MDNS_OS(tvOS)` instead of using this macro directly. 101 1.1 christos */ 102 1.1 christos #if defined(TARGET_OS_TV) && TARGET_OS_TV 103 1.1 christos #define MDNS_OS_PRIVATE_DEFINITION_tvOS() 1 104 1.1 christos #else 105 1.1 christos #define MDNS_OS_PRIVATE_DEFINITION_tvOS() 0 106 1.1 christos #endif 107 1.1 christos 108 1.1 christos // Time conversion constants 109 1.1 christos 110 1.1 christos #define MDNS_NANOSECONDS_PER_SECOND 1000000000 111 1.1 christos #define MDNS_MILLISECONDS_PER_SECOND 1000 112 1.1 christos #define MDNS_MILLISECONDS_PER_MINUTE (MDNS_MILLISECONDS_PER_SECOND * MDNS_SECONDS_PER_MINUTE) 113 1.1 christos #define MDNS_MILLISECONDS_PER_HOUR (MDNS_MILLISECONDS_PER_SECOND * MDNS_SECONDS_PER_HOUR) 114 1.1 christos #define MDNS_SECONDS_PER_MINUTE 60 115 1.1 christos #define MDNS_SECONDS_PER_HOUR (MDNS_SECONDS_PER_MINUTE * MDNS_MINUTES_PER_HOUR) 116 1.1 christos #define MDNS_SECONDS_PER_DAY (MDNS_SECONDS_PER_HOUR * MDNS_HOUR_PER_DAY) 117 1.1 christos #define MDNS_MINUTES_PER_HOUR 60 118 1.1 christos #define MDNS_HOUR_PER_DAY 24 119 1.1 christos 120 1.1 christos // Clang's __has_*() builtin macros are defined as zero if not defined. 121 1.1 christos 122 1.1 christos #if !defined(__has_attribute) 123 1.1 christos #define __has_attribute(X) 0 124 1.1 christos #endif 125 1.1 christos #if !defined(__has_extension) 126 1.1 christos #define __has_extension(X) 0 127 1.1 christos #endif 128 1.1 christos #if !defined(__has_feature) 129 1.1 christos #define __has_feature(X) 0 130 1.1 christos #endif 131 1.1 christos 132 1.1 christos /*! 133 1.1 christos * @brief 134 1.1 christos * Evaluates to non-zero if the compiler is Clang. 135 1.1 christos * 136 1.1 christos * @discussion 137 1.1 christos * __clang__ is defined when compiling with Clang, see 138 1.1 christos * <https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros>. 139 1.1 christos */ 140 1.1 christos #if defined(__clang__) 141 1.1 christos #define MDNS_COMPILER_IS_CLANG() 1 142 1.1 christos #else 143 1.1 christos #define MDNS_COMPILER_IS_CLANG() 0 144 1.1 christos #endif 145 1.1 christos 146 1.1 christos /*! 147 1.1 christos * @brief 148 1.1 christos * Evaluates to non-zero if the compiler is Clang and its version is at least a specified version. 149 1.1 christos * 150 1.1 christos * @param MAJOR 151 1.1 christos * The specified version's major number. 152 1.1 christos * 153 1.1 christos * @param MINOR 154 1.1 christos * The specified version's minor number. 155 1.1 christos * 156 1.1 christos * @param PATCH_LEVEL 157 1.1 christos * The specified version's patch level. 158 1.1 christos * 159 1.1 christos * @discussion 160 1.1 christos * Clang version numbers are of the form "<major number>.<minor number>.<patch level>". See 161 1.1 christos * <https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros> 162 1.1 christos */ 163 1.1 christos #if MDNS_COMPILER_IS_CLANG() 164 1.1 christos #define MDNS_CLANG_VERSION_IS_AT_LEAST(MAJOR, MINOR, PATCH_LEVEL) ( \ 165 1.1 christos (__clang_major__ > (MAJOR)) || ( \ 166 1.1 christos (__clang_major__ == (MAJOR)) && ( \ 167 1.1 christos (__clang_minor__ > (MINOR)) || ( \ 168 1.1 christos (__clang_minor__ == (MINOR)) && (__clang_patchlevel__ >= (PATCH_LEVEL)) \ 169 1.1 christos ) \ 170 1.1 christos ) \ 171 1.1 christos ) \ 172 1.1 christos ) 173 1.1 christos #else 174 1.1 christos #define MDNS_CLANG_VERSION_IS_AT_LEAST(MAJOR, MINOR, PATCH_LEVEL) 0 175 1.1 christos #endif 176 1.1 christos 177 1.1 christos /*! 178 1.1 christos * @brief 179 1.1 christos * Stringizes the argument and passes it to the _Pragma() operator, which takes a string literal argument. 180 1.1 christos * 181 1.1 christos * @param ARG 182 1.1 christos * The argument. 183 1.1 christos * 184 1.1 christos * @discussion 185 1.1 christos * Useful for escaping double quotes. For example, 186 1.1 christos * 187 1.1 christos * MDNS_PRAGMA_WITH_STRINGIZED_ARGUMENT(clang diagnostic ignored "-Wpadded") 188 1.1 christos * 189 1.1 christos * turns into 190 1.1 christos * 191 1.1 christos * _Pragma("clang diagnostic ignored \"-Wpadded\"") 192 1.1 christos * 193 1.1 christos * See <https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html>. 194 1.1 christos */ 195 1.1 christos #define MDNS_PRAGMA_WITH_STRINGIZED_ARGUMENT(ARG) _Pragma(#ARG) 196 1.1 christos 197 1.1 christos /*! 198 1.1 christos * @brief 199 1.1 christos * For Clang, starts ignoring the specified warning diagnostic flag. 200 1.1 christos * 201 1.1 christos * @param WARNING 202 1.1 christos * The warning diagnostic flag. 203 1.1 christos * 204 1.1 christos * @discussion 205 1.1 christos * Use MDNS_CLANG_IGNORE_WARNING_END() to undo the effect of this macro. 206 1.1 christos */ 207 1.1 christos #if MDNS_COMPILER_IS_CLANG() 208 1.1 christos #define MDNS_CLANG_IGNORE_WARNING_BEGIN(WARNING) \ 209 1.1 christos _Pragma("clang diagnostic push") \ 210 1.1 christos MDNS_PRAGMA_WITH_STRINGIZED_ARGUMENT(clang diagnostic ignored #WARNING) 211 1.1 christos #else 212 1.1 christos #define MDNS_CLANG_IGNORE_WARNING_BEGIN(WARNING) 213 1.1 christos #endif 214 1.1 christos 215 1.1 christos /*! 216 1.1 christos * @brief 217 1.1 christos * Use to undo the effect of a previous MDNS_CLANG_IGNORE_WARNING_BEGIN(). 218 1.1 christos */ 219 1.1 christos #if MDNS_COMPILER_IS_CLANG() 220 1.1 christos #define MDNS_CLANG_IGNORE_WARNING_END() _Pragma("clang diagnostic pop") 221 1.1 christos #else 222 1.1 christos #define MDNS_CLANG_IGNORE_WARNING_END() 223 1.1 christos #endif 224 1.1 christos 225 1.1 christos /*! 226 1.1 christos * @brief 227 1.1 christos * An alternative version of MDNS_CLANG_IGNORE_WARNING_BEGIN() that looks nicer when used among statements. 228 1.1 christos * 229 1.1 christos * @discussion 230 1.1 christos * This version looks nicer when used among C statements. Here's an example: 231 1.1 christos * 232 1.1 christos * mdns_clang_ignore_warning_begin(-Wformat-nonliteral); 233 1.1 christos * const int n = vsnprintf(dst, len, fmt, args); 234 1.1 christos * mdns_clang_ignore_warning_end(); 235 1.1 christos */ 236 1.1 christos #define mdns_clang_ignore_warning_begin(WARNING) \ 237 1.1 christos MDNS_CLANG_IGNORE_WARNING_BEGIN(WARNING) \ 238 1.1 christos do {} while (0) 239 1.1 christos 240 1.1 christos /*! 241 1.1 christos * @brief 242 1.1 christos * An alternative version of MDNS_CLANG_IGNORE_WARNING_END() that looks nicer when used among statements. 243 1.1 christos * 244 1.1 christos * @discussion 245 1.1 christos * This version looks nicer when used among C statements. Here's an example: 246 1.1 christos * 247 1.1 christos * mdns_clang_ignore_warning_begin(-Wformat-nonliteral); 248 1.1 christos * const int n = vsnprintf(dst, len, fmt, args); 249 1.1 christos * mdns_clang_ignore_warning_end(); 250 1.1 christos */ 251 1.1 christos #define mdns_clang_ignore_warning_end() \ 252 1.1 christos MDNS_CLANG_IGNORE_WARNING_END() \ 253 1.1 christos do {} while (0) 254 1.1 christos 255 1.1 christos /*! 256 1.1 christos * @brief 257 1.1 christos * For Clang, starts ignoring the -Wunaligned-access warning diagnostic flag. 258 1.1 christos * 259 1.1 christos * @discussion 260 1.1 christos * The -Wunaligned-access is new in clang version 14.0.3. This macro allow us to conditionally ignore 261 1.1 christos * -Wunaligned-access with Clang 14.0.3 or later. This avoids -Wunknown-warning-option warnings with 262 1.1 christos * earlier Clang versions, which don't recognize -Wunaligned-access. 263 1.1 christos */ 264 1.1 christos #if MDNS_CLANG_VERSION_IS_AT_LEAST(14, 0, 3) 265 1.1 christos #define MDNS_CLANG_IGNORE_UNALIGNED_ACCESS_WARNING_BEGIN() MDNS_CLANG_IGNORE_WARNING_BEGIN(-Wunaligned-access) 266 1.1 christos #else 267 1.1 christos #define MDNS_CLANG_IGNORE_UNALIGNED_ACCESS_WARNING_BEGIN() 268 1.1 christos #endif 269 1.1 christos 270 1.1 christos /*! 271 1.1 christos * @brief 272 1.1 christos * Undoes the effect of a previous MDNS_CLANG_IGNORE_UNALIGNED_ACCESS_WARNING_BEGIN(). 273 1.1 christos */ 274 1.1 christos #if MDNS_CLANG_VERSION_IS_AT_LEAST(14, 0, 3) 275 1.1 christos #define MDNS_CLANG_IGNORE_UNALIGNED_ACCESS_WARNING_END() MDNS_CLANG_IGNORE_WARNING_END() 276 1.1 christos #else 277 1.1 christos #define MDNS_CLANG_IGNORE_UNALIGNED_ACCESS_WARNING_END() 278 1.1 christos #endif 279 1.1 christos 280 1.1 christos /*! 281 1.1 christos * @brief 282 1.1 christos * For Clang, starts ignoring the -Wincompatible-function-pointer-types-strict warning diagnostic flag. 283 1.1 christos * 284 1.1 christos * @discussion 285 1.1 christos * -Wincompatible-function-pointer-types-strict is like -Wincompatible-function-pointer-types, but is more 286 1.1 christos * strict in that it warns about function pointer types that are not identical but are still compatible. 287 1.1 christos * 288 1.1 christos * The -Wincompatible-function-pointer-types-strict is new in clang version 16.0.0 (see 289 1.1 christos * https://releases.llvm.org/16.0.0/tools/clang/docs/ReleaseNotes.html). This macro allow us to 290 1.1 christos * conditionally ignore -Wincompatible-function-pointer-types-strict with Clang 16.0.0 or later. This 291 1.1 christos * avoids -Wunknown-warning-option warnings with earlier Clang versions, which don't recognize 292 1.1 christos * -Wincompatible-function-pointer-types-strict. 293 1.1 christos */ 294 1.1 christos #if MDNS_CLANG_VERSION_IS_AT_LEAST(16, 0, 0) 295 1.1 christos #define MDNS_CLANG_IGNORE_INCOMPATIBLE_FUNCTION_POINTER_TYPES_STRICT_WARNING_BEGIN() \ 296 1.1 christos MDNS_CLANG_IGNORE_WARNING_BEGIN(-Wincompatible-function-pointer-types-strict) 297 1.1 christos #else 298 1.1 christos #define MDNS_CLANG_IGNORE_INCOMPATIBLE_FUNCTION_POINTER_TYPES_STRICT_WARNING_BEGIN() 299 1.1 christos #endif 300 1.1 christos 301 1.1 christos /*! 302 1.1 christos * @brief 303 1.1 christos * Undoes the effect of a previous 304 1.1 christos * MDNS_CLANG_IGNORE_INCOMPATIBLE_FUNCTION_POINTER_TYPES_STRICT_WARNING_BEGIN(). 305 1.1 christos */ 306 1.1 christos #if MDNS_CLANG_VERSION_IS_AT_LEAST(16, 0, 0) 307 1.1 christos #define MDNS_CLANG_IGNORE_INCOMPATIBLE_FUNCTION_POINTER_TYPES_STRICT_WARNING_END() MDNS_CLANG_IGNORE_WARNING_END() 308 1.1 christos #else 309 1.1 christos #define MDNS_CLANG_IGNORE_INCOMPATIBLE_FUNCTION_POINTER_TYPES_STRICT_WARNING_END() 310 1.1 christos #endif 311 1.1 christos 312 1.1 christos /*! 313 1.1 christos * @brief 314 1.1 christos * For Clang, treats the specified warning diagnostic flag as an error. 315 1.1 christos * 316 1.1 christos * @param WARNING 317 1.1 christos * The warning diagnostic flag. 318 1.1 christos * 319 1.1 christos * @discussion 320 1.1 christos * Use MDNS_CLANG_TREAT_WARNING_AS_ERROR_END() to undo the effect of this macro. 321 1.1 christos */ 322 1.1 christos #if MDNS_COMPILER_IS_CLANG() 323 1.1 christos #define MDNS_CLANG_TREAT_WARNING_AS_ERROR_BEGIN(WARNING) \ 324 1.1 christos _Pragma("clang diagnostic push") \ 325 1.1 christos MDNS_PRAGMA_WITH_STRINGIZED_ARGUMENT(clang diagnostic error #WARNING) 326 1.1 christos #else 327 1.1 christos #define MDNS_CLANG_TREAT_WARNING_AS_ERROR_BEGIN(WARNING) 328 1.1 christos #endif 329 1.1 christos 330 1.1 christos /*! 331 1.1 christos * @brief 332 1.1 christos * Undoes the effect of a previous MDNS_CLANG_TREAT_WARNING_AS_ERROR_BEGIN(). 333 1.1 christos */ 334 1.1 christos #if MDNS_COMPILER_IS_CLANG() 335 1.1 christos #define MDNS_CLANG_TREAT_WARNING_AS_ERROR_END() _Pragma("clang diagnostic pop") 336 1.1 christos #else 337 1.1 christos #define MDNS_CLANG_TREAT_WARNING_AS_ERROR_END() 338 1.1 christos #endif 339 1.1 christos 340 1.1 christos /*! 341 1.1 christos * @brief 342 1.1 christos * For Clang, specifies that pointers without a nullability qualifier are _Nonnull. 343 1.1 christos * 344 1.1 christos * @discussion 345 1.1 christos * See <https://clang.llvm.org/docs/AttributeReference.html#nullability-attributes>. 346 1.1 christos */ 347 1.1 christos #if (MDNS_COMPILER_IS_CLANG() && __has_feature(assume_nonnull)) 348 1.1 christos #define MDNS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") 349 1.1 christos #else 350 1.1 christos #define MDNS_ASSUME_NONNULL_BEGIN 351 1.1 christos #endif 352 1.1 christos 353 1.1 christos /*! 354 1.1 christos * @brief 355 1.1 christos * Undoes the effect of a previous MDNS_ASSUME_NONNULL_BEGIN. 356 1.1 christos */ 357 1.1 christos #if (MDNS_COMPILER_IS_CLANG() && __has_feature(assume_nonnull)) 358 1.1 christos #define MDNS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") 359 1.1 christos #else 360 1.1 christos #define MDNS_ASSUME_NONNULL_END 361 1.1 christos #endif 362 1.1 christos 363 1.1 christos /*! 364 1.1 christos * @brief 365 1.1 christos * If supported, an attribute for closed enumeration definitions. 366 1.1 christos * 367 1.1 christos * @discussion 368 1.1 christos * See <https://clang.llvm.org/docs/AttributeReference.html#enum-extensibility>. 369 1.1 christos */ 370 1.1 christos #if __has_attribute(enum_extensibility) 371 1.1 christos #define MDNS_ENUM_ATTR_CLOSED __attribute__((enum_extensibility(closed))) 372 1.1 christos #else 373 1.1 christos #define MDNS_ENUM_ATTR_CLOSED 374 1.1 christos #endif 375 1.1 christos 376 1.1 christos /*! 377 1.1 christos * @brief 378 1.1 christos * If supported, defines a fixed-width closed enumeration. 379 1.1 christos * 380 1.1 christos * @param NAME 381 1.1 christos * The name of the enumeration. 382 1.1 christos * 383 1.1 christos * @param UNDERLYING_TYPE 384 1.1 christos * The enumeration's underlying type. 385 1.1 christos * 386 1.1 christos * @param ... 387 1.1 christos * The enumerator list. 388 1.1 christos * 389 1.1 christos * @discussion 390 1.1 christos * See <https://clang.llvm.org/docs/LanguageExtensions.html#enumerations-with-a-fixed-underlying-type> and 391 1.1 christos * <https://clang.llvm.org/docs/AttributeReference.html#enum-extensibility>. 392 1.1 christos */ 393 1.1 christos #if (__has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum) || __has_extension(cxx_strong_enums)) 394 1.1 christos #define MDNS_CLOSED_ENUM(NAME, UNDERLYING_TYPE, ...) \ 395 1.1 christos typedef enum : UNDERLYING_TYPE { \ 396 1.1 christos __VA_ARGS__ \ 397 1.1 christos } MDNS_ENUM_ATTR_CLOSED NAME 398 1.1 christos #else 399 1.1 christos #define MDNS_CLOSED_ENUM(NAME, UNDERLYING_TYPE, ...) \ 400 1.1 christos typedef UNDERLYING_TYPE NAME; \ 401 1.1 christos enum NAME ## _enum { \ 402 1.1 christos __VA_ARGS__ \ 403 1.1 christos } MDNS_ENUM_ATTR_CLOSED 404 1.1 christos #endif 405 1.1 christos 406 1.1 christos /*! 407 1.1 christos * @brief 408 1.1 christos * If supported, an attribute for flag-like enumeration definitions. 409 1.1 christos * 410 1.1 christos * @discussion 411 1.1 christos * See <https://clang.llvm.org/docs/AttributeReference.html#flag-enum>. 412 1.1 christos */ 413 1.1 christos #if __has_attribute(flag_enum) 414 1.1 christos #define MDNS_ENUM_ATTR_FLAG __attribute__((flag_enum)) 415 1.1 christos #else 416 1.1 christos #define MDNS_ENUM_ATTR_FLAG 417 1.1 christos #endif 418 1.1 christos 419 1.1 christos /*! 420 1.1 christos * @brief 421 1.1 christos * If supported, defines a fixed-width closed flag-like enumeration. 422 1.1 christos * 423 1.1 christos * @param NAME 424 1.1 christos * The name of the enumeration. 425 1.1 christos * 426 1.1 christos * @param UNDERLYING_TYPE 427 1.1 christos * The enumeration's underlying type. 428 1.1 christos * 429 1.1 christos * @param ... 430 1.1 christos * The enumeratior list. 431 1.1 christos * 432 1.1 christos * @discussion 433 1.1 christos * See <https://clang.llvm.org/docs/LanguageExtensions.html#enumerations-with-a-fixed-underlying-type> and 434 1.1 christos * <https://clang.llvm.org/docs/AttributeReference.html#flag-enum>. 435 1.1 christos */ 436 1.1 christos #if (__has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum) || __has_extension(cxx_strong_enums)) 437 1.1 christos #define MDNS_CLOSED_OPTIONS(NAME, UNDERLYING_TYPE, ...) \ 438 1.1 christos typedef enum : UNDERLYING_TYPE { \ 439 1.1 christos __VA_ARGS__ \ 440 1.1 christos } MDNS_ENUM_ATTR_CLOSED MDNS_ENUM_ATTR_FLAG NAME 441 1.1 christos #else 442 1.1 christos #define MDNS_CLOSED_OPTIONS(NAME, UNDERLYING_TYPE, ...) \ 443 1.1 christos typedef UNDERLYING_TYPE NAME; \ 444 1.1 christos enum NAME ## _enum { \ 445 1.1 christos __VA_ARGS__ \ 446 1.1 christos } MDNS_ENUM_ATTR_CLOSED MDNS_ENUM_ATTR_FLAG 447 1.1 christos #endif 448 1.1 christos 449 1.1 christos /*! 450 1.1 christos * @brief 451 1.1 christos * For compatibility with C++, marks the beginning of C function declarations. 452 1.1 christos * 453 1.1 christos * @discussion 454 1.1 christos * See <https://en.cppreference.com/w/cpp/language/language_linkage>. 455 1.1 christos */ 456 1.1 christos #if defined(__cplusplus) 457 1.1 christos #define MDNS_C_DECLARATIONS_BEGIN extern "C" { 458 1.1 christos #else 459 1.1 christos #define MDNS_C_DECLARATIONS_BEGIN 460 1.1 christos #endif 461 1.1 christos 462 1.1 christos /*! 463 1.1 christos * @brief 464 1.1 christos * For compatibility with C++, marks the end of C function declarations. 465 1.1 christos * 466 1.1 christos * @discussion 467 1.1 christos * This is the counterpart to MDNS_C_DECLARATIONS_BEGIN. 468 1.1 christos */ 469 1.1 christos #if defined(__cplusplus) 470 1.1 christos #define MDNS_C_DECLARATIONS_END } 471 1.1 christos #else 472 1.1 christos #define MDNS_C_DECLARATIONS_END 473 1.1 christos #endif 474 1.1 christos 475 1.1 christos /*! 476 1.1 christos * @brief 477 1.1 christos * Evaluates to non-zero if the compiler conforms to a specific minimum C standard. 478 1.1 christos * 479 1.1 christos * @param STANDARD 480 1.1 christos * The C standard. 481 1.1 christos */ 482 1.1 christos #define MDNS_C_STANDARD_IS_AT_LEAST(STANDARD) MDNS_C_STANDARD_PRIVATE_DEFINITION_IS_AT_LEAST_ ## STANDARD () 483 1.1 christos 484 1.1 christos /*! 485 1.1 christos * @brief 486 1.1 christos * Evaluates to non-zero if the compiler confroms to the C99 standard or later. 487 1.1 christos * 488 1.1 christos * @discussion 489 1.1 christos * __STDC_VERSION__ is a predefined macro that expands to 199901L for the C99 standard. See 490 1.1 christos * <https://en.cppreference.com/w/c/preprocessor/replace>. 491 1.1 christos * 492 1.1 christos * Use `MDNS_C_STANDARD_IS_AT_LEAST(C99)` instead of using this macro directly. 493 1.1 christos */ 494 1.1 christos #if defined(__STDC_VERSION__) 495 1.1 christos #define MDNS_C_STANDARD_PRIVATE_DEFINITION_IS_AT_LEAST_C99() (__STDC_VERSION__ >= 199901L) 496 1.1 christos #else 497 1.1 christos #define MDNS_C_STANDARD_PRIVATE_DEFINITION_IS_AT_LEAST_C99() 0 498 1.1 christos #endif 499 1.1 christos 500 1.1 christos /*! 501 1.1 christos * @brief 502 1.1 christos * Evaluates to non-zero if the compiler confroms to the C11 standard or later. 503 1.1 christos * 504 1.1 christos * @discussion 505 1.1 christos * __STDC_VERSION__ is a predefined macro that expands to 201112L for the C11 standard. See 506 1.1 christos * <https://en.cppreference.com/w/c/preprocessor/replace>. 507 1.1 christos * 508 1.1 christos * Use `MDNS_C_STANDARD_IS_AT_LEAST(C11)` instead of using this macro directly. 509 1.1 christos */ 510 1.1 christos #if defined(__STDC_VERSION__) 511 1.1 christos #define MDNS_C_STANDARD_PRIVATE_DEFINITION_IS_AT_LEAST_C11() (__STDC_VERSION__ >= 201112L) 512 1.1 christos #else 513 1.1 christos #define MDNS_C_STANDARD_PRIVATE_DEFINITION_IS_AT_LEAST_C11() 0 514 1.1 christos #endif 515 1.1 christos 516 1.1 christos /*! 517 1.1 christos * @brief 518 1.1 christos * Evaluates to non-zero if the compiler conforms to a specific minimum C++ standard. 519 1.1 christos * 520 1.1 christos * @param STANDARD 521 1.1 christos * The C standard. 522 1.1 christos */ 523 1.1 christos #define MDNS_CPP_STANDARD_IS_AT_LEAST(STANDARD) MDNS_CPP_STANDARD_PRIVATE_DEFINITION_IS_AT_LEAST_ ## STANDARD () 524 1.1 christos 525 1.1 christos /*! 526 1.1 christos * @brief 527 1.1 christos * Evaluates to non-zero if the compiler confroms to the C++11 standard or later. 528 1.1 christos * 529 1.1 christos * @discussion 530 1.1 christos * __cplusplus is a predefined macro that expands to 201103L for the C++11 standard. See 531 1.1 christos * <https://en.cppreference.com/w/cpp/preprocessor/replace>. 532 1.1 christos * 533 1.1 christos * Use `MDNS_CPP_STANDARD_IS_AT_LEAST(CPP11)` instead of using this macro directly. 534 1.1 christos */ 535 1.1 christos #if defined(__cplusplus) 536 1.1 christos #define MDNS_CPP_STANDARD_PRIVATE_DEFINITION_IS_AT_LEAST_CPP11() (__cplusplus >= 201103L) 537 1.1 christos #else 538 1.1 christos #define MDNS_CPP_STANDARD_PRIVATE_DEFINITION_IS_AT_LEAST_CPP11() 0 539 1.1 christos #endif 540 1.1 christos 541 1.1 christos /*! 542 1.1 christos * @brief 543 1.1 christos * Causes a compile-time error if an expression evaluates to false. 544 1.1 christos * 545 1.1 christos * @param EXPRESSION 546 1.1 christos * The expression. 547 1.1 christos * 548 1.1 christos * @param MESSAGE 549 1.1 christos * If supported, a sting literal to include as a diagnostic message if the expression evaluates to false. 550 1.1 christos */ 551 1.1 christos #if MDNS_C_STANDARD_IS_AT_LEAST(C11) 552 1.1 christos #define mdns_compile_time_check(EXPRESSION, MESSAGE) _Static_assert(EXPRESSION, MESSAGE) 553 1.1 christos #elif MDNS_CPP_STANDARD_IS_AT_LEAST(CPP11) 554 1.1 christos #define mdns_compile_time_check(EXPRESSION, MESSAGE) static_assert(EXPRESSION, MESSAGE) 555 1.1 christos #elif defined(__cplusplus) 556 1.1 christos #define mdns_compile_time_check(EXPRESSION, MESSAGE) \ 557 1.1 christos extern "C" int mdns_compile_time_check_failed[(EXPRESSION) ? 1 : -1] 558 1.1 christos #else 559 1.1 christos #define mdns_compile_time_check(EXPRESSION, MESSAGE) \ 560 1.1 christos extern int mdns_compile_time_check_failed[(EXPRESSION) ? 1 : -1] 561 1.1 christos #endif 562 1.1 christos 563 1.1 christos /*! 564 1.1 christos * @brief 565 1.1 christos * Causes a compile-time error if an expression evaluates to false. 566 1.1 christos * 567 1.1 christos * @param EXPRESSION 568 1.1 christos * The expression. 569 1.1 christos * 570 1.1 christos * @discussion 571 1.1 christos * This macro is meant to be used in a local scope, i.e., inside of a function or a block. For the global 572 1.1 christos * scope, use `mdns_compile_time_check()`. 573 1.1 christos * 574 1.1 christos * The fallback implementation is based on code from 575 1.1 christos * <https://www.drdobbs.com/compile-time-assertions/184401873>. 576 1.1 christos */ 577 1.1 christos #if MDNS_C_STANDARD_IS_AT_LEAST(C11) 578 1.1 christos #define mdns_compile_time_check_local(EXPRESSION) _Static_assert(EXPRESSION, "Compile-time assertion failed.") 579 1.1 christos #elif MDNS_CPP_STANDARD_IS_AT_LEAST(CPP11) 580 1.1 christos #define mdns_compile_time_check_local(EXPRESSION) static_assert(EXPRESSION, "Compile-time assertion failed.") 581 1.1 christos #else 582 1.1 christos #define mdns_compile_time_check_local(EXPRESSION) \ 583 1.1 christos do { \ 584 1.1 christos enum { \ 585 1.1 christos mdns_compile_time_check_local_failed = 1 / ((EXPRESSION) ? 1 : 0) \ 586 1.1 christos }; \ 587 1.1 christos } while (0) 588 1.1 christos #endif 589 1.1 christos 590 1.1 christos /*! 591 1.1 christos * @brief 592 1.1 christos * Determines at compile-time if the size of a type exceeds a specified maximum. 593 1.1 christos * 594 1.1 christos * @param TYPE 595 1.1 christos * The type. 596 1.1 christos * 597 1.1 christos * @param MAX_SIZE 598 1.1 christos * The maximum size in bytes. 599 1.1 christos */ 600 1.1 christos #define mdns_compile_time_max_size_check(TYPE, MAX_SIZE) \ 601 1.1 christos mdns_compile_time_check(sizeof(TYPE) <= MAX_SIZE, "The size of " # TYPE " exceeds max size of '" # MAX_SIZE "'.") 602 1.1 christos 603 1.1 christos /*! 604 1.1 christos * @brief 605 1.1 christos * Determines the size of an array's element type. 606 1.1 christos * 607 1.1 christos * @param ARRAY 608 1.1 christos * The array. 609 1.1 christos */ 610 1.1 christos #define mdns_sizeof_element(ARRAY) sizeof(ARRAY[0]) 611 1.1 christos 612 1.1 christos /*! 613 1.1 christos * @brief 614 1.1 christos * Determines the size of a member variable from a struct or union. 615 1.1 christos * 616 1.1 christos * @param TYPE 617 1.1 christos * The type name of the struct or union. 618 1.1 christos * 619 1.1 christos * @param MEMBER 620 1.1 christos * The name of the member variable. 621 1.1 christos */ 622 1.1 christos #define mdns_sizeof_member(TYPE, MEMBER) sizeof(((TYPE *)0)->MEMBER) 623 1.1 christos 624 1.1 christos /*! 625 1.1 christos * @brief 626 1.1 christos * Determines the number of elements in an array. 627 1.1 christos * 628 1.1 christos * @param ARRAY 629 1.1 christos * The array. 630 1.1 christos */ 631 1.1 christos #define mdns_countof(ARRAY) (sizeof(ARRAY) / mdns_sizeof_element(ARRAY)) 632 1.1 christos 633 1.1 christos /*! 634 1.1 christos * @brief 635 1.1 christos * If an expression evaluates to false, transfers control to a goto label. 636 1.1 christos * 637 1.1 christos * @param EXPRESSION 638 1.1 christos * The expression. 639 1.1 christos * 640 1.1 christos * @param LABEL 641 1.1 christos * The location's goto label. 642 1.1 christos * 643 1.1 christos * @discussion 644 1.1 christos * No debugging information is logged. 645 1.1 christos */ 646 1.1 christos #define mdns_require_quiet(EXPRESSION, LABEL) \ 647 1.1 christos do { \ 648 1.1 christos if (!(EXPRESSION)) { \ 649 1.1 christos goto LABEL; \ 650 1.1 christos } \ 651 1.1 christos } while (0) 652 1.1 christos 653 1.1 christos /*! 654 1.1 christos * @brief 655 1.1 christos * If an expression evaluates to false, executes an action, then transfers control to a goto label. 656 1.1 christos * 657 1.1 christos * @param EXPRESSION 658 1.1 christos * The expression. 659 1.1 christos * 660 1.1 christos * @param LABEL 661 1.1 christos * The goto label. 662 1.1 christos * 663 1.1 christos * @param ACTION 664 1.1 christos * The code to execute. 665 1.1 christos * 666 1.1 christos * @discussion 667 1.1 christos * No debugging information is logged. 668 1.1 christos */ 669 1.1 christos #define mdns_require_action_quiet(EXPRESSION, LABEL, ACTION) \ 670 1.1 christos do { \ 671 1.1 christos if (!(EXPRESSION)) { \ 672 1.1 christos { \ 673 1.1 christos ACTION; \ 674 1.1 christos } \ 675 1.1 christos goto LABEL; \ 676 1.1 christos } \ 677 1.1 christos } while (0) 678 1.1 christos 679 1.1 christos /*! 680 1.1 christos * @brief 681 1.1 christos * If an error code is non-zero, transfers control to a goto label. 682 1.1 christos * 683 1.1 christos * @param ERROR 684 1.1 christos * The error code. 685 1.1 christos * 686 1.1 christos * @param LABEL 687 1.1 christos * The location's goto label. 688 1.1 christos * 689 1.1 christos * @discussion 690 1.1 christos * No debugging information is logged. 691 1.1 christos */ 692 1.1 christos #define mdns_require_noerr_quiet(ERROR, LABEL) mdns_require_quiet(!(ERROR), LABEL) 693 1.1 christos 694 1.1 christos /*! 695 1.1 christos * @brief 696 1.1 christos * If an error code is non-zero, executes an action, then transfers control to a goto label. 697 1.1 christos * 698 1.1 christos * @param ERROR 699 1.1 christos * The error code. 700 1.1 christos * 701 1.1 christos * @param LABEL 702 1.1 christos * The location's goto label. 703 1.1 christos * 704 1.1 christos * @param ACTION 705 1.1 christos * The code to execute. 706 1.1 christos * 707 1.1 christos * @discussion 708 1.1 christos * No debugging information is logged. 709 1.1 christos */ 710 1.1 christos #define mdns_require_noerr_action_quiet(ERROR, LABEL, ACTION) mdns_require_action_quiet(!(ERROR), LABEL, ACTION) 711 1.1 christos 712 1.1 christos /*! 713 1.1 christos * @brief 714 1.1 christos * Returns from the current function if an expression evaluates to false. 715 1.1 christos * 716 1.1 christos * @param EXPRESSION 717 1.1 christos * The expression. 718 1.1 christos */ 719 1.1 christos #define mdns_require_return(EXPRESSION) \ 720 1.1 christos do { \ 721 1.1 christos if (!(EXPRESSION)) { \ 722 1.1 christos return; \ 723 1.1 christos } \ 724 1.1 christos } while (0) 725 1.1 christos 726 1.1 christos /*! 727 1.1 christos * @brief 728 1.1 christos * If an expression evaluates to false, executes an action, then returns. 729 1.1 christos * 730 1.1 christos * @param EXPRESSION 731 1.1 christos * The expression. 732 1.1 christos * 733 1.1 christos * @param ACTION 734 1.1 christos * The code to execute. 735 1.1 christos * 736 1.1 christos * @discussion 737 1.1 christos * No debugging information is logged. 738 1.1 christos */ 739 1.1 christos #define mdns_require_return_action(EXPRESSION, ACTION) \ 740 1.1 christos do { \ 741 1.1 christos if (!(EXPRESSION)) { \ 742 1.1 christos { \ 743 1.1 christos ACTION; \ 744 1.1 christos } \ 745 1.1 christos return; \ 746 1.1 christos } \ 747 1.1 christos } while (0) 748 1.1 christos 749 1.1 christos /*! 750 1.1 christos * @brief 751 1.1 christos * Returns from the current function with a specified value if an expression evaluates to false. 752 1.1 christos * 753 1.1 christos * @param EXPRESSION 754 1.1 christos * The expression. 755 1.1 christos * 756 1.1 christos * @param VALUE 757 1.1 christos * The return value. 758 1.1 christos */ 759 1.1 christos #define mdns_require_return_value(EXPRESSION, VALUE) \ 760 1.1 christos do { \ 761 1.1 christos if (!(EXPRESSION)) { \ 762 1.1 christos return (VALUE); \ 763 1.1 christos } \ 764 1.1 christos } while (0) 765 1.1 christos 766 1.1 christos /*! 767 1.1 christos * @brief 768 1.1 christos * Returns from the current function with a specified return value if an error code is non-zero. 769 1.1 christos * 770 1.1 christos * @param ERROR 771 1.1 christos * The error code. 772 1.1 christos * 773 1.1 christos * @param VALUE 774 1.1 christos * The return value. 775 1.1 christos */ 776 1.1 christos #define mdns_require_noerr_return_value(ERROR, VALUE) mdns_require_return_value(!(ERROR), VALUE) 777 1.1 christos 778 1.1 christos /*! 779 1.1 christos * @brief 780 1.1 christos * Assigns a value to a variable if the variable's address isn't NULL. 781 1.1 christos * 782 1.1 christos * @param VARIABLE_ADDR 783 1.1 christos * The variable's address. 784 1.1 christos * 785 1.1 christos * @param VALUE 786 1.1 christos * The value. 787 1.1 christos */ 788 1.1 christos #define mdns_assign(VARIABLE_ADDR, VALUE) \ 789 1.1 christos do { \ 790 1.1 christos if (VARIABLE_ADDR) { \ 791 1.1 christos *(VARIABLE_ADDR) = (VALUE); \ 792 1.1 christos } \ 793 1.1 christos } while (0) 794 1.1 christos 795 1.1 christos /*! 796 1.1 christos * @brief 797 1.1 christos * Declares an array of bytes that is meant to be used as explicit padding at the end of a struct. 798 1.1 christos * 799 1.1 christos * @param BYTE_COUNT 800 1.1 christos * The size of the array in number of bytes. 801 1.1 christos * 802 1.1 christos * @discussion 803 1.1 christos * This explicit padding is meant to be used as the final member variable of a struct to eliminate the 804 1.1 christos * -Wpadded warning about a struct's overall size being implicitly padded up to an alignment boundary. 805 1.1 christos * In other words, in place of such implicit padding, use this explicit padding instead. 806 1.1 christos */ 807 1.1 christos #define MDNS_STRUCT_PAD(BYTE_COUNT) \ 808 1.1 christos MDNS_CLANG_IGNORE_WARNING_BEGIN(-Wzero-length-array) \ 809 1.1 christos char _mdns_unused_padding[(BYTE_COUNT)] \ 810 1.1 christos MDNS_CLANG_IGNORE_WARNING_END() 811 1.1 christos 812 1.1 christos /*! 813 1.1 christos * @brief 814 1.1 christos * Like MDNS_STRUCT_PAD(), except that the amount of padding is specified for 64-bit and 32-bit platforms. 815 1.1 christos * 816 1.1 christos * @param BYTE_COUNT_64 817 1.1 christos * The amount of padding in number of bytes to use on 64-bit platforms. 818 1.1 christos * 819 1.1 christos * @param BYTE_COUNT_32 820 1.1 christos * The amount of padding in number of bytes to use on 32-bit platforms. 821 1.1 christos * 822 1.1 christos * @discussion 823 1.1 christos * This macro assumes that pointers on 64-bit platforms are eight bytes in size and that pointers on 32-bit 824 1.1 christos * platforms are four bytes in size. 825 1.1 christos * 826 1.1 christos * If the size of a pointer is something other than eight or four bytes, then a compiler error will occur. 827 1.1 christos */ 828 1.1 christos #define MDNS_STRUCT_PAD_64_32(BYTE_COUNT_64, BYTE_COUNT_32) \ 829 1.1 christos MDNS_STRUCT_PAD( \ 830 1.1 christos (sizeof(void *) == 8) ? BYTE_COUNT_64 : \ 831 1.1 christos (sizeof(void *) == 4) ? BYTE_COUNT_32 : -1 \ 832 1.1 christos ) 833 1.1 christos 834 1.1 christos /*! 835 1.1 christos * @brief 836 1.1 christos * Compile-time check to ensure that a struct that uses MDNS_STRUCT_PAD() or MDNS_STRUCT_PAD_64_32() hasn't 837 1.1 christos * specified too much padding. 838 1.1 christos * 839 1.1 christos * @param STRUCT_TYPE 840 1.1 christos * The struct type. 841 1.1 christos * 842 1.1 christos * @discussion 843 1.1 christos * There's too much padding if the padding's size is greater than or equal to the struct's alignment 844 1.1 christos * requirement. This is because the point of MDNS_STRUCT_PAD() and MDNS_STRUCT_PAD_64_32() is to explicitly 845 1.1 christos * pad a struct up to a multiple of the struct's alignment requirement. Violating this check would 846 1.1 christos * unnecessarily increase the size of the struct. 847 1.1 christos */ 848 1.1 christos #define MDNS_GENERAL_STRUCT_PAD_CHECK(STRUCT_TYPE) \ 849 1.1 christos mdns_compile_time_check(mdns_sizeof_member(STRUCT_TYPE, _mdns_unused_padding) < _Alignof(STRUCT_TYPE), \ 850 1.1 christos "Padding exceeds alignment of '" # STRUCT_TYPE "', so the amount of padding is excessive.") 851 1.1 christos 852 1.1 christos /*! 853 1.1 christos * @brief 854 1.1 christos * Retains a Core Foundation object if the specified object reference is non-NULL. 855 1.1 christos * 856 1.1 christos * @param OBJ 857 1.1 christos * A reference to the object to retain. 858 1.1 christos * 859 1.1 christos * @discussion 860 1.1 christos * The object reference is explicitly compared against NULL to avoid a warning from the Clang analyzer's 861 1.1 christos * osx.NumberObjectConversion checker. See 862 1.1 christos * <https://clang.llvm.org/docs/analyzer/checkers.html#osx-numberobjectconversion-c-c-objc>. 863 1.1 christos */ 864 1.1 christos #define mdns_cf_retain_null_safe(OBJ) \ 865 1.1 christos do { \ 866 1.1 christos if ((OBJ) != NULL) { \ 867 1.1 christos CFRetain((OBJ)); \ 868 1.1 christos } \ 869 1.1 christos } while (0) 870 1.1 christos 871 1.1 christos /*! 872 1.1 christos * @brief 873 1.1 christos * Releases the Core Foundation object referenced by a pointer. 874 1.1 christos * 875 1.1 christos * @param OBJ_PTR 876 1.1 christos * The address of the pointer that either references a Core Foundation object or references NULL. 877 1.1 christos * 878 1.1 christos * @discussion 879 1.1 christos * If the pointer contains a non-NULL reference, then the pointer will be set to NULL after releasing the 880 1.1 christos * object. 881 1.1 christos * 882 1.1 christos * The object reference is explicitly compared against NULL to avoid a warning from the Clang analyzer's 883 1.1 christos * osx.NumberObjectConversion checker. See 884 1.1 christos * <https://clang.llvm.org/docs/analyzer/checkers.html#osx-numberobjectconversion-c-c-objc>. 885 1.1 christos */ 886 1.1 christos #define mdns_cf_forget(OBJ_PTR) \ 887 1.1 christos do { \ 888 1.1 christos if (*(OBJ_PTR) != NULL) { \ 889 1.1 christos CFRelease(*(OBJ_PTR)); \ 890 1.1 christos *(OBJ_PTR) = NULL; \ 891 1.1 christos } \ 892 1.1 christos } while (0) 893 1.1 christos 894 1.1 christos /*! 895 1.1 christos * @brief 896 1.1 christos * Alternative to the `default` label in a switch statement that covers all enumeration values. 897 1.1 christos * 898 1.1 christos * @discussion 899 1.1 christos * Use `MDNS_COVERED_SWITCH_DEFAULT` instead of `default` to avoid the `-Wcovered-switch-default` warning 900 1.1 christos * in a switch statement that covers all enumeration values. This macro is useful when strict enforcement 901 1.1 christos * of the `-Wswitch-default` warning compels us to include a default label in such switch statements. 902 1.1 christos */ 903 1.1 christos #if MDNS_COMPILER_IS_CLANG() 904 1.1 christos #define MDNS_COVERED_SWITCH_DEFAULT \ 905 1.1 christos MDNS_CLANG_IGNORE_WARNING_BEGIN(-Wcovered-switch-default) \ 906 1.1 christos default \ 907 1.1 christos MDNS_CLANG_IGNORE_WARNING_END() 908 1.1 christos #else 909 1.1 christos #define MDNS_COVERED_SWITCH_DEFAULT default 910 1.1 christos #endif 911 1.1 christos 912 1.1 christos /*! 913 1.1 christos * @brief 914 1.1 christos * The static keyword for array parameters for C99 or later. 915 1.1 christos * 916 1.1 christos * @discussion 917 1.1 christos * See <https://en.cppreference.com/w/c/language/operator_other#Function_call>. 918 1.1 christos */ 919 1.1 christos #if MDNS_C_STANDARD_IS_AT_LEAST(C99) 920 1.1 christos #define MDNS_STATIC_ARRAY_PARAM static 921 1.1 christos #else 922 1.1 christos #define MDNS_STATIC_ARRAY_PARAM 923 1.1 christos #endif 924 1.1 christos 925 1.1 christos /*! 926 1.1 christos * @brief 927 1.1 christos * The size of a Universally Unique Identifier (UUID) in bytes. 928 1.1 christos * 929 1.1 christos * @discussion 930 1.1 christos * See <https://datatracker.ietf.org/doc/html/rfc4122#section-4.1>. 931 1.1 christos */ 932 1.1 christos #define MDNS_UUID_SIZE 16 933 1.1 christos 934 1.1 christos #endif // MDNS_GENERAL_H 935