build-mac/curl/typecheck-gcc.h
changeset 340 ff99a398d872
child 531 a7cc26cc39f2
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/build-mac/curl/typecheck-gcc.h	Mon Aug 24 17:23:37 2015 +0200
     1.3 @@ -0,0 +1,612 @@
     1.4 +#ifndef __CURL_TYPECHECK_GCC_H
     1.5 +#define __CURL_TYPECHECK_GCC_H
     1.6 +/***************************************************************************
     1.7 + *                                  _   _ ____  _
     1.8 + *  Project                     ___| | | |  _ \| |
     1.9 + *                             / __| | | | |_) | |
    1.10 + *                            | (__| |_| |  _ <| |___
    1.11 + *                             \___|\___/|_| \_\_____|
    1.12 + *
    1.13 + * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
    1.14 + *
    1.15 + * This software is licensed as described in the file COPYING, which
    1.16 + * you should have received as part of this distribution. The terms
    1.17 + * are also available at http://curl.haxx.se/docs/copyright.html.
    1.18 + *
    1.19 + * You may opt to use, copy, modify, merge, publish, distribute and/or sell
    1.20 + * copies of the Software, and permit persons to whom the Software is
    1.21 + * furnished to do so, under the terms of the COPYING file.
    1.22 + *
    1.23 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
    1.24 + * KIND, either express or implied.
    1.25 + *
    1.26 + ***************************************************************************/
    1.27 +
    1.28 +/* wraps curl_easy_setopt() with typechecking */
    1.29 +
    1.30 +/* To add a new kind of warning, add an
    1.31 + *   if(_curl_is_sometype_option(_curl_opt))
    1.32 + *     if(!_curl_is_sometype(value))
    1.33 + *       _curl_easy_setopt_err_sometype();
    1.34 + * block and define _curl_is_sometype_option, _curl_is_sometype and
    1.35 + * _curl_easy_setopt_err_sometype below
    1.36 + *
    1.37 + * NOTE: We use two nested 'if' statements here instead of the && operator, in
    1.38 + *       order to work around gcc bug #32061.  It affects only gcc 4.3.x/4.4.x
    1.39 + *       when compiling with -Wlogical-op.
    1.40 + *
    1.41 + * To add an option that uses the same type as an existing option, you'll just
    1.42 + * need to extend the appropriate _curl_*_option macro
    1.43 + */
    1.44 +#define curl_easy_setopt(handle, option, value)                               \
    1.45 +__extension__ ({                                                              \
    1.46 +  __typeof__ (option) _curl_opt = option;                                     \
    1.47 +  if(__builtin_constant_p(_curl_opt)) {                                       \
    1.48 +    if(_curl_is_long_option(_curl_opt))                                       \
    1.49 +      if(!_curl_is_long(value))                                               \
    1.50 +        _curl_easy_setopt_err_long();                                         \
    1.51 +    if(_curl_is_off_t_option(_curl_opt))                                      \
    1.52 +      if(!_curl_is_off_t(value))                                              \
    1.53 +        _curl_easy_setopt_err_curl_off_t();                                   \
    1.54 +    if(_curl_is_string_option(_curl_opt))                                     \
    1.55 +      if(!_curl_is_string(value))                                             \
    1.56 +        _curl_easy_setopt_err_string();                                       \
    1.57 +    if(_curl_is_write_cb_option(_curl_opt))                                   \
    1.58 +      if(!_curl_is_write_cb(value))                                           \
    1.59 +        _curl_easy_setopt_err_write_callback();                               \
    1.60 +    if((_curl_opt) == CURLOPT_READFUNCTION)                                   \
    1.61 +      if(!_curl_is_read_cb(value))                                            \
    1.62 +        _curl_easy_setopt_err_read_cb();                                      \
    1.63 +    if((_curl_opt) == CURLOPT_IOCTLFUNCTION)                                  \
    1.64 +      if(!_curl_is_ioctl_cb(value))                                           \
    1.65 +        _curl_easy_setopt_err_ioctl_cb();                                     \
    1.66 +    if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION)                                \
    1.67 +      if(!_curl_is_sockopt_cb(value))                                         \
    1.68 +        _curl_easy_setopt_err_sockopt_cb();                                   \
    1.69 +    if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION)                             \
    1.70 +      if(!_curl_is_opensocket_cb(value))                                      \
    1.71 +        _curl_easy_setopt_err_opensocket_cb();                                \
    1.72 +    if((_curl_opt) == CURLOPT_PROGRESSFUNCTION)                               \
    1.73 +      if(!_curl_is_progress_cb(value))                                        \
    1.74 +        _curl_easy_setopt_err_progress_cb();                                  \
    1.75 +    if((_curl_opt) == CURLOPT_DEBUGFUNCTION)                                  \
    1.76 +      if(!_curl_is_debug_cb(value))                                           \
    1.77 +        _curl_easy_setopt_err_debug_cb();                                     \
    1.78 +    if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION)                               \
    1.79 +      if(!_curl_is_ssl_ctx_cb(value))                                         \
    1.80 +        _curl_easy_setopt_err_ssl_ctx_cb();                                   \
    1.81 +    if(_curl_is_conv_cb_option(_curl_opt))                                    \
    1.82 +      if(!_curl_is_conv_cb(value))                                            \
    1.83 +        _curl_easy_setopt_err_conv_cb();                                      \
    1.84 +    if((_curl_opt) == CURLOPT_SEEKFUNCTION)                                   \
    1.85 +      if(!_curl_is_seek_cb(value))                                            \
    1.86 +        _curl_easy_setopt_err_seek_cb();                                      \
    1.87 +    if(_curl_is_cb_data_option(_curl_opt))                                    \
    1.88 +      if(!_curl_is_cb_data(value))                                            \
    1.89 +        _curl_easy_setopt_err_cb_data();                                      \
    1.90 +    if((_curl_opt) == CURLOPT_ERRORBUFFER)                                    \
    1.91 +      if(!_curl_is_error_buffer(value))                                       \
    1.92 +        _curl_easy_setopt_err_error_buffer();                                 \
    1.93 +    if((_curl_opt) == CURLOPT_STDERR)                                         \
    1.94 +      if(!_curl_is_FILE(value))                                               \
    1.95 +        _curl_easy_setopt_err_FILE();                                         \
    1.96 +    if(_curl_is_postfields_option(_curl_opt))                                 \
    1.97 +      if(!_curl_is_postfields(value))                                         \
    1.98 +        _curl_easy_setopt_err_postfields();                                   \
    1.99 +    if((_curl_opt) == CURLOPT_HTTPPOST)                                       \
   1.100 +      if(!_curl_is_arr((value), struct curl_httppost))                        \
   1.101 +        _curl_easy_setopt_err_curl_httpost();                                 \
   1.102 +    if(_curl_is_slist_option(_curl_opt))                                      \
   1.103 +      if(!_curl_is_arr((value), struct curl_slist))                           \
   1.104 +        _curl_easy_setopt_err_curl_slist();                                   \
   1.105 +    if((_curl_opt) == CURLOPT_SHARE)                                          \
   1.106 +      if(!_curl_is_ptr((value), CURLSH))                                      \
   1.107 +        _curl_easy_setopt_err_CURLSH();                                       \
   1.108 +  }                                                                           \
   1.109 +  curl_easy_setopt(handle, _curl_opt, value);                                 \
   1.110 +})
   1.111 +
   1.112 +/* wraps curl_easy_getinfo() with typechecking */
   1.113 +/* FIXME: don't allow const pointers */
   1.114 +#define curl_easy_getinfo(handle, info, arg)                                  \
   1.115 +__extension__ ({                                                              \
   1.116 +  __typeof__ (info) _curl_info = info;                                        \
   1.117 +  if(__builtin_constant_p(_curl_info)) {                                      \
   1.118 +    if(_curl_is_string_info(_curl_info))                                      \
   1.119 +      if(!_curl_is_arr((arg), char *))                                        \
   1.120 +        _curl_easy_getinfo_err_string();                                      \
   1.121 +    if(_curl_is_long_info(_curl_info))                                        \
   1.122 +      if(!_curl_is_arr((arg), long))                                          \
   1.123 +        _curl_easy_getinfo_err_long();                                        \
   1.124 +    if(_curl_is_double_info(_curl_info))                                      \
   1.125 +      if(!_curl_is_arr((arg), double))                                        \
   1.126 +        _curl_easy_getinfo_err_double();                                      \
   1.127 +    if(_curl_is_slist_info(_curl_info))                                       \
   1.128 +      if(!_curl_is_arr((arg), struct curl_slist *))                           \
   1.129 +        _curl_easy_getinfo_err_curl_slist();                                  \
   1.130 +  }                                                                           \
   1.131 +  curl_easy_getinfo(handle, _curl_info, arg);                                 \
   1.132 +})
   1.133 +
   1.134 +/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
   1.135 + * for now just make sure that the functions are called with three
   1.136 + * arguments
   1.137 + */
   1.138 +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
   1.139 +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
   1.140 +
   1.141 +
   1.142 +/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
   1.143 + * functions */
   1.144 +
   1.145 +/* To define a new warning, use _CURL_WARNING(identifier, "message") */
   1.146 +#define _CURL_WARNING(id, message)                                            \
   1.147 +  static void __attribute__((__warning__(message)))                           \
   1.148 +  __attribute__((__unused__)) __attribute__((__noinline__))                   \
   1.149 +  id(void) { __asm__(""); }
   1.150 +
   1.151 +_CURL_WARNING(_curl_easy_setopt_err_long,
   1.152 +  "curl_easy_setopt expects a long argument for this option")
   1.153 +_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
   1.154 +  "curl_easy_setopt expects a curl_off_t argument for this option")
   1.155 +_CURL_WARNING(_curl_easy_setopt_err_string,
   1.156 +              "curl_easy_setopt expects a "
   1.157 +              "string (char* or char[]) argument for this option"
   1.158 +  )
   1.159 +_CURL_WARNING(_curl_easy_setopt_err_write_callback,
   1.160 +  "curl_easy_setopt expects a curl_write_callback argument for this option")
   1.161 +_CURL_WARNING(_curl_easy_setopt_err_read_cb,
   1.162 +  "curl_easy_setopt expects a curl_read_callback argument for this option")
   1.163 +_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
   1.164 +  "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
   1.165 +_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
   1.166 +  "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
   1.167 +_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
   1.168 +              "curl_easy_setopt expects a "
   1.169 +              "curl_opensocket_callback argument for this option"
   1.170 +  )
   1.171 +_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
   1.172 +  "curl_easy_setopt expects a curl_progress_callback argument for this option")
   1.173 +_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
   1.174 +  "curl_easy_setopt expects a curl_debug_callback argument for this option")
   1.175 +_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
   1.176 +  "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
   1.177 +_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
   1.178 +  "curl_easy_setopt expects a curl_conv_callback argument for this option")
   1.179 +_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
   1.180 +  "curl_easy_setopt expects a curl_seek_callback argument for this option")
   1.181 +_CURL_WARNING(_curl_easy_setopt_err_cb_data,
   1.182 +              "curl_easy_setopt expects a "
   1.183 +              "private data pointer as argument for this option")
   1.184 +_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
   1.185 +              "curl_easy_setopt expects a "
   1.186 +              "char buffer of CURL_ERROR_SIZE as argument for this option")
   1.187 +_CURL_WARNING(_curl_easy_setopt_err_FILE,
   1.188 +  "curl_easy_setopt expects a FILE* argument for this option")
   1.189 +_CURL_WARNING(_curl_easy_setopt_err_postfields,
   1.190 +  "curl_easy_setopt expects a void* or char* argument for this option")
   1.191 +_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
   1.192 +  "curl_easy_setopt expects a struct curl_httppost* argument for this option")
   1.193 +_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
   1.194 +  "curl_easy_setopt expects a struct curl_slist* argument for this option")
   1.195 +_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
   1.196 +  "curl_easy_setopt expects a CURLSH* argument for this option")
   1.197 +
   1.198 +_CURL_WARNING(_curl_easy_getinfo_err_string,
   1.199 +  "curl_easy_getinfo expects a pointer to char * for this info")
   1.200 +_CURL_WARNING(_curl_easy_getinfo_err_long,
   1.201 +  "curl_easy_getinfo expects a pointer to long for this info")
   1.202 +_CURL_WARNING(_curl_easy_getinfo_err_double,
   1.203 +  "curl_easy_getinfo expects a pointer to double for this info")
   1.204 +_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
   1.205 +  "curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
   1.206 +
   1.207 +/* groups of curl_easy_setops options that take the same type of argument */
   1.208 +
   1.209 +/* To add a new option to one of the groups, just add
   1.210 + *   (option) == CURLOPT_SOMETHING
   1.211 + * to the or-expression. If the option takes a long or curl_off_t, you don't
   1.212 + * have to do anything
   1.213 + */
   1.214 +
   1.215 +/* evaluates to true if option takes a long argument */
   1.216 +#define _curl_is_long_option(option)                                          \
   1.217 +  (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
   1.218 +
   1.219 +#define _curl_is_off_t_option(option)                                         \
   1.220 +  ((option) > CURLOPTTYPE_OFF_T)
   1.221 +
   1.222 +/* evaluates to true if option takes a char* argument */
   1.223 +#define _curl_is_string_option(option)                                        \
   1.224 +  ((option) == CURLOPT_URL ||                                                 \
   1.225 +   (option) == CURLOPT_PROXY ||                                               \
   1.226 +   (option) == CURLOPT_INTERFACE ||                                           \
   1.227 +   (option) == CURLOPT_NETRC_FILE ||                                          \
   1.228 +   (option) == CURLOPT_USERPWD ||                                             \
   1.229 +   (option) == CURLOPT_USERNAME ||                                            \
   1.230 +   (option) == CURLOPT_PASSWORD ||                                            \
   1.231 +   (option) == CURLOPT_PROXYUSERPWD ||                                        \
   1.232 +   (option) == CURLOPT_PROXYUSERNAME ||                                       \
   1.233 +   (option) == CURLOPT_PROXYPASSWORD ||                                       \
   1.234 +   (option) == CURLOPT_NOPROXY ||                                             \
   1.235 +   (option) == CURLOPT_ACCEPT_ENCODING ||                                     \
   1.236 +   (option) == CURLOPT_REFERER ||                                             \
   1.237 +   (option) == CURLOPT_USERAGENT ||                                           \
   1.238 +   (option) == CURLOPT_COOKIE ||                                              \
   1.239 +   (option) == CURLOPT_COOKIEFILE ||                                          \
   1.240 +   (option) == CURLOPT_COOKIEJAR ||                                           \
   1.241 +   (option) == CURLOPT_COOKIELIST ||                                          \
   1.242 +   (option) == CURLOPT_FTPPORT ||                                             \
   1.243 +   (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                             \
   1.244 +   (option) == CURLOPT_FTP_ACCOUNT ||                                         \
   1.245 +   (option) == CURLOPT_RANGE ||                                               \
   1.246 +   (option) == CURLOPT_CUSTOMREQUEST ||                                       \
   1.247 +   (option) == CURLOPT_SSLCERT ||                                             \
   1.248 +   (option) == CURLOPT_SSLCERTTYPE ||                                         \
   1.249 +   (option) == CURLOPT_SSLKEY ||                                              \
   1.250 +   (option) == CURLOPT_SSLKEYTYPE ||                                          \
   1.251 +   (option) == CURLOPT_KEYPASSWD ||                                           \
   1.252 +   (option) == CURLOPT_SSLENGINE ||                                           \
   1.253 +   (option) == CURLOPT_CAINFO ||                                              \
   1.254 +   (option) == CURLOPT_CAPATH ||                                              \
   1.255 +   (option) == CURLOPT_RANDOM_FILE ||                                         \
   1.256 +   (option) == CURLOPT_EGDSOCKET ||                                           \
   1.257 +   (option) == CURLOPT_SSL_CIPHER_LIST ||                                     \
   1.258 +   (option) == CURLOPT_KRBLEVEL ||                                            \
   1.259 +   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
   1.260 +   (option) == CURLOPT_SSH_PUBLIC_KEYFILE ||                                  \
   1.261 +   (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                                 \
   1.262 +   (option) == CURLOPT_CRLFILE ||                                             \
   1.263 +   (option) == CURLOPT_ISSUERCERT ||                                          \
   1.264 +   (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE ||                               \
   1.265 +   (option) == CURLOPT_SSH_KNOWNHOSTS ||                                      \
   1.266 +   (option) == CURLOPT_MAIL_FROM ||                                           \
   1.267 +   (option) == CURLOPT_RTSP_SESSION_ID ||                                     \
   1.268 +   (option) == CURLOPT_RTSP_STREAM_URI ||                                     \
   1.269 +   (option) == CURLOPT_RTSP_TRANSPORT ||                                      \
   1.270 +   (option) == CURLOPT_XOAUTH2_BEARER ||                                      \
   1.271 +   (option) == CURLOPT_DNS_SERVERS ||                                         \
   1.272 +   (option) == CURLOPT_DNS_INTERFACE ||                                       \
   1.273 +   (option) == CURLOPT_DNS_LOCAL_IP4 ||                                       \
   1.274 +   (option) == CURLOPT_DNS_LOCAL_IP6 ||                                       \
   1.275 +   (option) == CURLOPT_LOGIN_OPTIONS ||                                       \
   1.276 +   (option) == CURLOPT_PROXY_SERVICE_NAME ||                                  \
   1.277 +   (option) == CURLOPT_SERVICE_NAME ||                                        \
   1.278 +   0)
   1.279 +
   1.280 +/* evaluates to true if option takes a curl_write_callback argument */
   1.281 +#define _curl_is_write_cb_option(option)                                      \
   1.282 +  ((option) == CURLOPT_HEADERFUNCTION ||                                      \
   1.283 +   (option) == CURLOPT_WRITEFUNCTION)
   1.284 +
   1.285 +/* evaluates to true if option takes a curl_conv_callback argument */
   1.286 +#define _curl_is_conv_cb_option(option)                                       \
   1.287 +  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                            \
   1.288 +   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                          \
   1.289 +   (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
   1.290 +
   1.291 +/* evaluates to true if option takes a data argument to pass to a callback */
   1.292 +#define _curl_is_cb_data_option(option)                                       \
   1.293 +  ((option) == CURLOPT_WRITEDATA ||                                           \
   1.294 +   (option) == CURLOPT_READDATA ||                                            \
   1.295 +   (option) == CURLOPT_IOCTLDATA ||                                           \
   1.296 +   (option) == CURLOPT_SOCKOPTDATA ||                                         \
   1.297 +   (option) == CURLOPT_OPENSOCKETDATA ||                                      \
   1.298 +   (option) == CURLOPT_PROGRESSDATA ||                                        \
   1.299 +   (option) == CURLOPT_HEADERDATA ||                                         \
   1.300 +   (option) == CURLOPT_DEBUGDATA ||                                           \
   1.301 +   (option) == CURLOPT_SSL_CTX_DATA ||                                        \
   1.302 +   (option) == CURLOPT_SEEKDATA ||                                            \
   1.303 +   (option) == CURLOPT_PRIVATE ||                                             \
   1.304 +   (option) == CURLOPT_SSH_KEYDATA ||                                         \
   1.305 +   (option) == CURLOPT_INTERLEAVEDATA ||                                      \
   1.306 +   (option) == CURLOPT_CHUNK_DATA ||                                          \
   1.307 +   (option) == CURLOPT_FNMATCH_DATA ||                                        \
   1.308 +   0)
   1.309 +
   1.310 +/* evaluates to true if option takes a POST data argument (void* or char*) */
   1.311 +#define _curl_is_postfields_option(option)                                    \
   1.312 +  ((option) == CURLOPT_POSTFIELDS ||                                          \
   1.313 +   (option) == CURLOPT_COPYPOSTFIELDS ||                                      \
   1.314 +   0)
   1.315 +
   1.316 +/* evaluates to true if option takes a struct curl_slist * argument */
   1.317 +#define _curl_is_slist_option(option)                                         \
   1.318 +  ((option) == CURLOPT_HTTPHEADER ||                                          \
   1.319 +   (option) == CURLOPT_HTTP200ALIASES ||                                      \
   1.320 +   (option) == CURLOPT_QUOTE ||                                               \
   1.321 +   (option) == CURLOPT_POSTQUOTE ||                                           \
   1.322 +   (option) == CURLOPT_PREQUOTE ||                                            \
   1.323 +   (option) == CURLOPT_TELNETOPTIONS ||                                       \
   1.324 +   (option) == CURLOPT_MAIL_RCPT ||                                           \
   1.325 +   0)
   1.326 +
   1.327 +/* groups of curl_easy_getinfo infos that take the same type of argument */
   1.328 +
   1.329 +/* evaluates to true if info expects a pointer to char * argument */
   1.330 +#define _curl_is_string_info(info)                                            \
   1.331 +  (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
   1.332 +
   1.333 +/* evaluates to true if info expects a pointer to long argument */
   1.334 +#define _curl_is_long_info(info)                                              \
   1.335 +  (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
   1.336 +
   1.337 +/* evaluates to true if info expects a pointer to double argument */
   1.338 +#define _curl_is_double_info(info)                                            \
   1.339 +  (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
   1.340 +
   1.341 +/* true if info expects a pointer to struct curl_slist * argument */
   1.342 +#define _curl_is_slist_info(info)                                             \
   1.343 +  (CURLINFO_SLIST < (info))
   1.344 +
   1.345 +
   1.346 +/* typecheck helpers -- check whether given expression has requested type*/
   1.347 +
   1.348 +/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
   1.349 + * otherwise define a new macro. Search for __builtin_types_compatible_p
   1.350 + * in the GCC manual.
   1.351 + * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
   1.352 + * the actual expression passed to the curl_easy_setopt macro. This
   1.353 + * means that you can only apply the sizeof and __typeof__ operators, no
   1.354 + * == or whatsoever.
   1.355 + */
   1.356 +
   1.357 +/* XXX: should evaluate to true iff expr is a pointer */
   1.358 +#define _curl_is_any_ptr(expr)                                                \
   1.359 +  (sizeof(expr) == sizeof(void*))
   1.360 +
   1.361 +/* evaluates to true if expr is NULL */
   1.362 +/* XXX: must not evaluate expr, so this check is not accurate */
   1.363 +#define _curl_is_NULL(expr)                                                   \
   1.364 +  (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
   1.365 +
   1.366 +/* evaluates to true if expr is type*, const type* or NULL */
   1.367 +#define _curl_is_ptr(expr, type)                                              \
   1.368 +  (_curl_is_NULL(expr) ||                                                     \
   1.369 +   __builtin_types_compatible_p(__typeof__(expr), type *) ||                  \
   1.370 +   __builtin_types_compatible_p(__typeof__(expr), const type *))
   1.371 +
   1.372 +/* evaluates to true if expr is one of type[], type*, NULL or const type* */
   1.373 +#define _curl_is_arr(expr, type)                                              \
   1.374 +  (_curl_is_ptr((expr), type) ||                                              \
   1.375 +   __builtin_types_compatible_p(__typeof__(expr), type []))
   1.376 +
   1.377 +/* evaluates to true if expr is a string */
   1.378 +#define _curl_is_string(expr)                                                 \
   1.379 +  (_curl_is_arr((expr), char) ||                                              \
   1.380 +   _curl_is_arr((expr), signed char) ||                                       \
   1.381 +   _curl_is_arr((expr), unsigned char))
   1.382 +
   1.383 +/* evaluates to true if expr is a long (no matter the signedness)
   1.384 + * XXX: for now, int is also accepted (and therefore short and char, which
   1.385 + * are promoted to int when passed to a variadic function) */
   1.386 +#define _curl_is_long(expr)                                                   \
   1.387 +  (__builtin_types_compatible_p(__typeof__(expr), long) ||                    \
   1.388 +   __builtin_types_compatible_p(__typeof__(expr), signed long) ||             \
   1.389 +   __builtin_types_compatible_p(__typeof__(expr), unsigned long) ||           \
   1.390 +   __builtin_types_compatible_p(__typeof__(expr), int) ||                     \
   1.391 +   __builtin_types_compatible_p(__typeof__(expr), signed int) ||              \
   1.392 +   __builtin_types_compatible_p(__typeof__(expr), unsigned int) ||            \
   1.393 +   __builtin_types_compatible_p(__typeof__(expr), short) ||                   \
   1.394 +   __builtin_types_compatible_p(__typeof__(expr), signed short) ||            \
   1.395 +   __builtin_types_compatible_p(__typeof__(expr), unsigned short) ||          \
   1.396 +   __builtin_types_compatible_p(__typeof__(expr), char) ||                    \
   1.397 +   __builtin_types_compatible_p(__typeof__(expr), signed char) ||             \
   1.398 +   __builtin_types_compatible_p(__typeof__(expr), unsigned char))
   1.399 +
   1.400 +/* evaluates to true if expr is of type curl_off_t */
   1.401 +#define _curl_is_off_t(expr)                                                  \
   1.402 +  (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
   1.403 +
   1.404 +/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
   1.405 +/* XXX: also check size of an char[] array? */
   1.406 +#define _curl_is_error_buffer(expr)                                           \
   1.407 +  (_curl_is_NULL(expr) ||                                                     \
   1.408 +   __builtin_types_compatible_p(__typeof__(expr), char *) ||                  \
   1.409 +   __builtin_types_compatible_p(__typeof__(expr), char[]))
   1.410 +
   1.411 +/* evaluates to true if expr is of type (const) void* or (const) FILE* */
   1.412 +#if 0
   1.413 +#define _curl_is_cb_data(expr)                                                \
   1.414 +  (_curl_is_ptr((expr), void) ||                                              \
   1.415 +   _curl_is_ptr((expr), FILE))
   1.416 +#else /* be less strict */
   1.417 +#define _curl_is_cb_data(expr)                                                \
   1.418 +  _curl_is_any_ptr(expr)
   1.419 +#endif
   1.420 +
   1.421 +/* evaluates to true if expr is of type FILE* */
   1.422 +#define _curl_is_FILE(expr)                                                   \
   1.423 +  (__builtin_types_compatible_p(__typeof__(expr), FILE *))
   1.424 +
   1.425 +/* evaluates to true if expr can be passed as POST data (void* or char*) */
   1.426 +#define _curl_is_postfields(expr)                                             \
   1.427 +  (_curl_is_ptr((expr), void) ||                                              \
   1.428 +   _curl_is_arr((expr), char))
   1.429 +
   1.430 +/* FIXME: the whole callback checking is messy...
   1.431 + * The idea is to tolerate char vs. void and const vs. not const
   1.432 + * pointers in arguments at least
   1.433 + */
   1.434 +/* helper: __builtin_types_compatible_p distinguishes between functions and
   1.435 + * function pointers, hide it */
   1.436 +#define _curl_callback_compatible(func, type)                                 \
   1.437 +  (__builtin_types_compatible_p(__typeof__(func), type) ||                    \
   1.438 +   __builtin_types_compatible_p(__typeof__(func), type*))
   1.439 +
   1.440 +/* evaluates to true if expr is of type curl_read_callback or "similar" */
   1.441 +#define _curl_is_read_cb(expr)                                          \
   1.442 +  (_curl_is_NULL(expr) ||                                                     \
   1.443 +   __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) ||       \
   1.444 +   __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) ||      \
   1.445 +   _curl_callback_compatible((expr), _curl_read_callback1) ||                 \
   1.446 +   _curl_callback_compatible((expr), _curl_read_callback2) ||                 \
   1.447 +   _curl_callback_compatible((expr), _curl_read_callback3) ||                 \
   1.448 +   _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
   1.449 +   _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
   1.450 +   _curl_callback_compatible((expr), _curl_read_callback6))
   1.451 +typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
   1.452 +typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
   1.453 +typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
   1.454 +typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
   1.455 +typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
   1.456 +typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
   1.457 +
   1.458 +/* evaluates to true if expr is of type curl_write_callback or "similar" */
   1.459 +#define _curl_is_write_cb(expr)                                               \
   1.460 +  (_curl_is_read_cb(expr) ||                                            \
   1.461 +   __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) ||      \
   1.462 +   __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) ||     \
   1.463 +   _curl_callback_compatible((expr), _curl_write_callback1) ||                \
   1.464 +   _curl_callback_compatible((expr), _curl_write_callback2) ||                \
   1.465 +   _curl_callback_compatible((expr), _curl_write_callback3) ||                \
   1.466 +   _curl_callback_compatible((expr), _curl_write_callback4) ||                \
   1.467 +   _curl_callback_compatible((expr), _curl_write_callback5) ||                \
   1.468 +   _curl_callback_compatible((expr), _curl_write_callback6))
   1.469 +typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
   1.470 +typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
   1.471 +                                       const void*);
   1.472 +typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
   1.473 +typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
   1.474 +typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
   1.475 +                                       const void*);
   1.476 +typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
   1.477 +
   1.478 +/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
   1.479 +#define _curl_is_ioctl_cb(expr)                                         \
   1.480 +  (_curl_is_NULL(expr) ||                                                     \
   1.481 +   __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) ||     \
   1.482 +   _curl_callback_compatible((expr), _curl_ioctl_callback1) ||                \
   1.483 +   _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
   1.484 +   _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
   1.485 +   _curl_callback_compatible((expr), _curl_ioctl_callback4))
   1.486 +typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
   1.487 +typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
   1.488 +typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
   1.489 +typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
   1.490 +
   1.491 +/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
   1.492 +#define _curl_is_sockopt_cb(expr)                                       \
   1.493 +  (_curl_is_NULL(expr) ||                                                     \
   1.494 +   __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) ||   \
   1.495 +   _curl_callback_compatible((expr), _curl_sockopt_callback1) ||              \
   1.496 +   _curl_callback_compatible((expr), _curl_sockopt_callback2))
   1.497 +typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
   1.498 +typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
   1.499 +                                      curlsocktype);
   1.500 +
   1.501 +/* evaluates to true if expr is of type curl_opensocket_callback or
   1.502 +   "similar" */
   1.503 +#define _curl_is_opensocket_cb(expr)                                    \
   1.504 +  (_curl_is_NULL(expr) ||                                                     \
   1.505 +   __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
   1.506 +   _curl_callback_compatible((expr), _curl_opensocket_callback1) ||           \
   1.507 +   _curl_callback_compatible((expr), _curl_opensocket_callback2) ||           \
   1.508 +   _curl_callback_compatible((expr), _curl_opensocket_callback3) ||           \
   1.509 +   _curl_callback_compatible((expr), _curl_opensocket_callback4))
   1.510 +typedef curl_socket_t (_curl_opensocket_callback1)
   1.511 +  (void *, curlsocktype, struct curl_sockaddr *);
   1.512 +typedef curl_socket_t (_curl_opensocket_callback2)
   1.513 +  (void *, curlsocktype, const struct curl_sockaddr *);
   1.514 +typedef curl_socket_t (_curl_opensocket_callback3)
   1.515 +  (const void *, curlsocktype, struct curl_sockaddr *);
   1.516 +typedef curl_socket_t (_curl_opensocket_callback4)
   1.517 +  (const void *, curlsocktype, const struct curl_sockaddr *);
   1.518 +
   1.519 +/* evaluates to true if expr is of type curl_progress_callback or "similar" */
   1.520 +#define _curl_is_progress_cb(expr)                                      \
   1.521 +  (_curl_is_NULL(expr) ||                                                     \
   1.522 +   __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) ||  \
   1.523 +   _curl_callback_compatible((expr), _curl_progress_callback1) ||             \
   1.524 +   _curl_callback_compatible((expr), _curl_progress_callback2))
   1.525 +typedef int (_curl_progress_callback1)(void *,
   1.526 +    double, double, double, double);
   1.527 +typedef int (_curl_progress_callback2)(const void *,
   1.528 +    double, double, double, double);
   1.529 +
   1.530 +/* evaluates to true if expr is of type curl_debug_callback or "similar" */
   1.531 +#define _curl_is_debug_cb(expr)                                         \
   1.532 +  (_curl_is_NULL(expr) ||                                                     \
   1.533 +   __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) ||     \
   1.534 +   _curl_callback_compatible((expr), _curl_debug_callback1) ||                \
   1.535 +   _curl_callback_compatible((expr), _curl_debug_callback2) ||                \
   1.536 +   _curl_callback_compatible((expr), _curl_debug_callback3) ||                \
   1.537 +   _curl_callback_compatible((expr), _curl_debug_callback4) ||                \
   1.538 +   _curl_callback_compatible((expr), _curl_debug_callback5) ||                \
   1.539 +   _curl_callback_compatible((expr), _curl_debug_callback6) ||                \
   1.540 +   _curl_callback_compatible((expr), _curl_debug_callback7) ||                \
   1.541 +   _curl_callback_compatible((expr), _curl_debug_callback8))
   1.542 +typedef int (_curl_debug_callback1) (CURL *,
   1.543 +    curl_infotype, char *, size_t, void *);
   1.544 +typedef int (_curl_debug_callback2) (CURL *,
   1.545 +    curl_infotype, char *, size_t, const void *);
   1.546 +typedef int (_curl_debug_callback3) (CURL *,
   1.547 +    curl_infotype, const char *, size_t, void *);
   1.548 +typedef int (_curl_debug_callback4) (CURL *,
   1.549 +    curl_infotype, const char *, size_t, const void *);
   1.550 +typedef int (_curl_debug_callback5) (CURL *,
   1.551 +    curl_infotype, unsigned char *, size_t, void *);
   1.552 +typedef int (_curl_debug_callback6) (CURL *,
   1.553 +    curl_infotype, unsigned char *, size_t, const void *);
   1.554 +typedef int (_curl_debug_callback7) (CURL *,
   1.555 +    curl_infotype, const unsigned char *, size_t, void *);
   1.556 +typedef int (_curl_debug_callback8) (CURL *,
   1.557 +    curl_infotype, const unsigned char *, size_t, const void *);
   1.558 +
   1.559 +/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
   1.560 +/* this is getting even messier... */
   1.561 +#define _curl_is_ssl_ctx_cb(expr)                                       \
   1.562 +  (_curl_is_NULL(expr) ||                                                     \
   1.563 +   __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) ||   \
   1.564 +   _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) ||              \
   1.565 +   _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) ||              \
   1.566 +   _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) ||              \
   1.567 +   _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) ||              \
   1.568 +   _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) ||              \
   1.569 +   _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) ||              \
   1.570 +   _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) ||              \
   1.571 +   _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
   1.572 +typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *);
   1.573 +typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
   1.574 +typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
   1.575 +typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
   1.576 +#ifdef HEADER_SSL_H
   1.577 +/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
   1.578 + * this will of course break if we're included before OpenSSL headers...
   1.579 + */
   1.580 +typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
   1.581 +typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
   1.582 +typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
   1.583 +typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX,
   1.584 +                                           const void *);
   1.585 +#else
   1.586 +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
   1.587 +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
   1.588 +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
   1.589 +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
   1.590 +#endif
   1.591 +
   1.592 +/* evaluates to true if expr is of type curl_conv_callback or "similar" */
   1.593 +#define _curl_is_conv_cb(expr)                                          \
   1.594 +  (_curl_is_NULL(expr) ||                                                     \
   1.595 +   __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) ||      \
   1.596 +   _curl_callback_compatible((expr), _curl_conv_callback1) ||                 \
   1.597 +   _curl_callback_compatible((expr), _curl_conv_callback2) ||                 \
   1.598 +   _curl_callback_compatible((expr), _curl_conv_callback3) ||                 \
   1.599 +   _curl_callback_compatible((expr), _curl_conv_callback4))
   1.600 +typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
   1.601 +typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
   1.602 +typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
   1.603 +typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
   1.604 +
   1.605 +/* evaluates to true if expr is of type curl_seek_callback or "similar" */
   1.606 +#define _curl_is_seek_cb(expr)                                          \
   1.607 +  (_curl_is_NULL(expr) ||                                                     \
   1.608 +   __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) ||      \
   1.609 +   _curl_callback_compatible((expr), _curl_seek_callback1) ||                 \
   1.610 +   _curl_callback_compatible((expr), _curl_seek_callback2))
   1.611 +typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
   1.612 +typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
   1.613 +
   1.614 +
   1.615 +#endif /* __CURL_TYPECHECK_GCC_H */