Planeshift

typecheck-gcc.h

Go to the documentation of this file.
00001 #ifndef __CURL_TYPECHECK_GCC_H
00002 #define __CURL_TYPECHECK_GCC_H
00003 /***************************************************************************
00004  *                                  _   _ ____  _
00005  *  Project                     ___| | | |  _ \| |
00006  *                             / __| | | | |_) | |
00007  *                            | (__| |_| |  _ <| |___
00008  *                             \___|\___/|_| \_\_____|
00009  *
00010  * Copyright (C) 1998 - 2009, Daniel Stenberg, <[email protected]>, et al.
00011  *
00012  * This software is licensed as described in the file COPYING, which
00013  * you should have received as part of this distribution. The terms
00014  * are also available at http://curl.haxx.se/docs/copyright.html.
00015  *
00016  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00017  * copies of the Software, and permit persons to whom the Software is
00018  * furnished to do so, under the terms of the COPYING file.
00019  *
00020  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00021  * KIND, either express or implied.
00022  *
00023  * $Id: typecheck-gcc.h 8795 2013-09-14 06:15:05Z joelyon $
00024  ***************************************************************************/
00025 
00026 /* wraps curl_easy_setopt() with typechecking */
00027 
00028 /* To add a new kind of warning, add an
00029  *   if(_curl_is_sometype_option(_curl_opt) && ! _curl_is_sometype(value))
00030  *     _curl_easy_setopt_err_sometype();
00031  * block and define _curl_is_sometype_option, _curl_is_sometype and
00032  * _curl_easy_setopt_err_sometype below
00033  *
00034  * To add an option that uses the same type as an existing option, you'll just
00035  * need to extend the appropriate _curl_*_option macro
00036  */
00037 #define curl_easy_setopt(handle, option, value)                               \
00038 __extension__ ({                                                              \
00039   __typeof__ (option) _curl_opt = option;                                     \
00040   if (__builtin_constant_p(_curl_opt)) {                                      \
00041     if (_curl_is_long_option(_curl_opt) && !_curl_is_long(value))             \
00042       _curl_easy_setopt_err_long();                                           \
00043     if (_curl_is_off_t_option(_curl_opt) && !_curl_is_off_t(value))           \
00044       _curl_easy_setopt_err_curl_off_t();                                     \
00045     if (_curl_is_string_option(_curl_opt) && !_curl_is_string(value))         \
00046       _curl_easy_setopt_err_string();                                         \
00047     if (_curl_is_write_cb_option(_curl_opt) && !_curl_is_write_cb(value))     \
00048       _curl_easy_setopt_err_write_callback();                                 \
00049     if ((_curl_opt) == CURLOPT_READFUNCTION && !_curl_is_read_cb(value))      \
00050       _curl_easy_setopt_err_read_cb();                                        \
00051     if ((_curl_opt) == CURLOPT_IOCTLFUNCTION && !_curl_is_ioctl_cb(value))    \
00052       _curl_easy_setopt_err_ioctl_cb();                                       \
00053     if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION && !_curl_is_sockopt_cb(value))\
00054       _curl_easy_setopt_err_sockopt_cb();                                     \
00055     if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION &&                          \
00056             !_curl_is_opensocket_cb(value))                                   \
00057       _curl_easy_setopt_err_opensocket_cb();                                  \
00058     if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION &&                            \
00059             !_curl_is_progress_cb(value))                                     \
00060       _curl_easy_setopt_err_progress_cb();                                    \
00061     if ((_curl_opt) == CURLOPT_DEBUGFUNCTION && !_curl_is_debug_cb(value))    \
00062       _curl_easy_setopt_err_debug_cb();                                       \
00063     if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION &&                            \
00064             !_curl_is_ssl_ctx_cb(value))                                      \
00065       _curl_easy_setopt_err_ssl_ctx_cb();                                     \
00066     if (_curl_is_conv_cb_option(_curl_opt) && !_curl_is_conv_cb(value))       \
00067       _curl_easy_setopt_err_conv_cb();                                        \
00068     if ((_curl_opt) == CURLOPT_SEEKFUNCTION && !_curl_is_seek_cb(value))      \
00069       _curl_easy_setopt_err_seek_cb();                                        \
00070     if (_curl_is_cb_data_option(_curl_opt) && !_curl_is_cb_data(value))       \
00071       _curl_easy_setopt_err_cb_data();                                        \
00072     if ((_curl_opt) == CURLOPT_ERRORBUFFER && !_curl_is_error_buffer(value))  \
00073       _curl_easy_setopt_err_error_buffer();                                   \
00074     if ((_curl_opt) == CURLOPT_STDERR && !_curl_is_FILE(value))               \
00075       _curl_easy_setopt_err_FILE();                                           \
00076     if (_curl_is_postfields_option(_curl_opt) && !_curl_is_postfields(value)) \
00077       _curl_easy_setopt_err_postfields();                                     \
00078     if ((_curl_opt) == CURLOPT_HTTPPOST &&                                    \
00079             !_curl_is_arr((value), struct curl_httppost))                     \
00080       _curl_easy_setopt_err_curl_httpost();                                   \
00081     if (_curl_is_slist_option(_curl_opt) &&                                   \
00082             !_curl_is_arr((value), struct curl_slist))                        \
00083       _curl_easy_setopt_err_curl_slist();                                     \
00084     if ((_curl_opt) == CURLOPT_SHARE && !_curl_is_ptr((value), CURLSH))       \
00085       _curl_easy_setopt_err_CURLSH();                                         \
00086   }                                                                           \
00087   curl_easy_setopt(handle, _curl_opt, value);                                 \
00088 })
00089 
00090 /* wraps curl_easy_getinfo() with typechecking */
00091 /* FIXME: don't allow const pointers */
00092 #define curl_easy_getinfo(handle, info, arg)                                  \
00093 __extension__ ({                                                              \
00094   __typeof__ (info) _curl_info = info;                                        \
00095   if (__builtin_constant_p(_curl_info)) {                                     \
00096     if (_curl_is_string_info(_curl_info) && !_curl_is_arr((arg), char *))     \
00097       _curl_easy_getinfo_err_string();                                        \
00098     if (_curl_is_long_info(_curl_info) && !_curl_is_arr((arg), long))         \
00099       _curl_easy_getinfo_err_long();                                          \
00100     if (_curl_is_double_info(_curl_info) && !_curl_is_arr((arg), double))     \
00101       _curl_easy_getinfo_err_double();                                        \
00102     if (_curl_is_slist_info(_curl_info) &&                                    \
00103            !_curl_is_arr((arg), struct curl_slist *))                         \
00104       _curl_easy_getinfo_err_curl_slist();                                    \
00105   }                                                                           \
00106   curl_easy_getinfo(handle, _curl_info, arg);                                 \
00107 })
00108 
00109 /* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
00110  * for now just make sure that the functions are called with three
00111  * arguments
00112  */
00113 #define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
00114 #define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
00115 
00116 
00117 /* the actual warnings, triggered by calling the _curl_easy_setopt_err*
00118  * functions */
00119 
00120 /* To define a new warning, use _CURL_WARNING(identifier, "message") */
00121 #define _CURL_WARNING(id, message)                                            \
00122   static void __attribute__((warning(message))) __attribute__((unused))       \
00123   __attribute__((noinline)) id(void) { __asm__(""); }
00124 
00125 _CURL_WARNING(_curl_easy_setopt_err_long,
00126   "curl_easy_setopt expects a long argument for this option")
00127 _CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
00128   "curl_easy_setopt expects a curl_off_t argument for this option")
00129 _CURL_WARNING(_curl_easy_setopt_err_string,
00130   "curl_easy_setopt expects a string (char* or char[]) argument for this option"
00131   )
00132 _CURL_WARNING(_curl_easy_setopt_err_write_callback,
00133   "curl_easy_setopt expects a curl_write_callback argument for this option")
00134 _CURL_WARNING(_curl_easy_setopt_err_read_cb,
00135   "curl_easy_setopt expects a curl_read_callback argument for this option")
00136 _CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
00137   "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
00138 _CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
00139   "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
00140 _CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
00141   "curl_easy_setopt expects a curl_opensocket_callback argument for this option"
00142   )
00143 _CURL_WARNING(_curl_easy_setopt_err_progress_cb,
00144   "curl_easy_setopt expects a curl_progress_callback argument for this option")
00145 _CURL_WARNING(_curl_easy_setopt_err_debug_cb,
00146   "curl_easy_setopt expects a curl_debug_callback argument for this option")
00147 _CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
00148   "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
00149 _CURL_WARNING(_curl_easy_setopt_err_conv_cb,
00150   "curl_easy_setopt expects a curl_conv_callback argument for this option")
00151 _CURL_WARNING(_curl_easy_setopt_err_seek_cb,
00152   "curl_easy_setopt expects a curl_seek_callback argument for this option")
00153 _CURL_WARNING(_curl_easy_setopt_err_cb_data,
00154   "curl_easy_setopt expects a private data pointer as argument for this option")
00155 _CURL_WARNING(_curl_easy_setopt_err_error_buffer,
00156   "curl_easy_setopt expects a char buffer of CURL_ERROR_SIZE as argument for this option")
00157 _CURL_WARNING(_curl_easy_setopt_err_FILE,
00158   "curl_easy_setopt expects a FILE* argument for this option")
00159 _CURL_WARNING(_curl_easy_setopt_err_postfields,
00160   "curl_easy_setopt expects a void* or char* argument for this option")
00161 _CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
00162   "curl_easy_setopt expects a struct curl_httppost* argument for this option")
00163 _CURL_WARNING(_curl_easy_setopt_err_curl_slist,
00164   "curl_easy_setopt expects a struct curl_slist* argument for this option")
00165 _CURL_WARNING(_curl_easy_setopt_err_CURLSH,
00166   "curl_easy_setopt expects a CURLSH* argument for this option")
00167 
00168 _CURL_WARNING(_curl_easy_getinfo_err_string,
00169   "curl_easy_getinfo expects a pointer to char * for this info")
00170 _CURL_WARNING(_curl_easy_getinfo_err_long,
00171   "curl_easy_getinfo expects a pointer to long for this info")
00172 _CURL_WARNING(_curl_easy_getinfo_err_double,
00173   "curl_easy_getinfo expects a pointer to double for this info")
00174 _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
00175   "curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
00176 
00177 /* groups of curl_easy_setops options that take the same type of argument */
00178 
00179 /* To add a new option to one of the groups, just add
00180  *   (option) == CURLOPT_SOMETHING
00181  * to the or-expression. If the option takes a long or curl_off_t, you don't
00182  * have to do anything
00183  */
00184 
00185 /* evaluates to true if option takes a long argument */
00186 #define _curl_is_long_option(option)                                          \
00187   (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
00188 
00189 #define _curl_is_off_t_option(option)                                         \
00190   ((option) > CURLOPTTYPE_OFF_T)
00191 
00192 /* evaluates to true if option takes a char* argument */
00193 #define _curl_is_string_option(option)                                        \
00194   ((option) == CURLOPT_URL ||                                                 \
00195    (option) == CURLOPT_PROXY ||                                               \
00196    (option) == CURLOPT_INTERFACE ||                                           \
00197    (option) == CURLOPT_NETRC_FILE ||                                          \
00198    (option) == CURLOPT_USERPWD ||                                             \
00199    (option) == CURLOPT_USERNAME ||                                            \
00200    (option) == CURLOPT_PASSWORD ||                                            \
00201    (option) == CURLOPT_PROXYUSERPWD ||                                        \
00202    (option) == CURLOPT_PROXYUSERNAME ||                                       \
00203    (option) == CURLOPT_PROXYPASSWORD ||                                       \
00204    (option) == CURLOPT_NOPROXY ||                                             \
00205    (option) == CURLOPT_ENCODING ||                                            \
00206    (option) == CURLOPT_REFERER ||                                             \
00207    (option) == CURLOPT_USERAGENT ||                                           \
00208    (option) == CURLOPT_COOKIE ||                                              \
00209    (option) == CURLOPT_COOKIEFILE ||                                          \
00210    (option) == CURLOPT_COOKIEJAR ||                                           \
00211    (option) == CURLOPT_COOKIELIST ||                                          \
00212    (option) == CURLOPT_FTPPORT ||                                             \
00213    (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                             \
00214    (option) == CURLOPT_FTP_ACCOUNT ||                                         \
00215    (option) == CURLOPT_RANGE ||                                               \
00216    (option) == CURLOPT_CUSTOMREQUEST ||                                       \
00217    (option) == CURLOPT_SSLCERT ||                                             \
00218    (option) == CURLOPT_SSLCERTTYPE ||                                         \
00219    (option) == CURLOPT_SSLKEY ||                                              \
00220    (option) == CURLOPT_SSLKEYTYPE ||                                          \
00221    (option) == CURLOPT_KEYPASSWD ||                                           \
00222    (option) == CURLOPT_SSLENGINE ||                                           \
00223    (option) == CURLOPT_CAINFO ||                                              \
00224    (option) == CURLOPT_CAPATH ||                                              \
00225    (option) == CURLOPT_RANDOM_FILE ||                                         \
00226    (option) == CURLOPT_EGDSOCKET ||                                           \
00227    (option) == CURLOPT_SSL_CIPHER_LIST ||                                     \
00228    (option) == CURLOPT_KRBLEVEL ||                                            \
00229    (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
00230    (option) == CURLOPT_SSH_PUBLIC_KEYFILE ||                                  \
00231    (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                                 \
00232    (option) == CURLOPT_CRLFILE ||                                             \
00233    (option) == CURLOPT_ISSUERCERT ||                                          \
00234    0)
00235 
00236 /* evaluates to true if option takes a curl_write_callback argument */
00237 #define _curl_is_write_cb_option(option)                                      \
00238   ((option) == CURLOPT_HEADERFUNCTION ||                                      \
00239    (option) == CURLOPT_WRITEFUNCTION)
00240 
00241 /* evaluates to true if option takes a curl_conv_callback argument */
00242 #define _curl_is_conv_cb_option(option)                                       \
00243   ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                            \
00244    (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                          \
00245    (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
00246 
00247 /* evaluates to true if option takes a data argument to pass to a callback */
00248 #define _curl_is_cb_data_option(option)                                       \
00249   ((option) == CURLOPT_WRITEDATA ||                                           \
00250    (option) == CURLOPT_READDATA ||                                            \
00251    (option) == CURLOPT_IOCTLDATA ||                                           \
00252    (option) == CURLOPT_SOCKOPTDATA ||                                         \
00253    (option) == CURLOPT_OPENSOCKETDATA ||                                      \
00254    (option) == CURLOPT_PROGRESSDATA ||                                        \
00255    (option) == CURLOPT_WRITEHEADER ||                                         \
00256    (option) == CURLOPT_DEBUGDATA ||                                           \
00257    (option) == CURLOPT_SSL_CTX_DATA ||                                        \
00258    (option) == CURLOPT_SEEKDATA ||                                            \
00259    (option) == CURLOPT_PRIVATE ||                                             \
00260    0)
00261 
00262 /* evaluates to true if option takes a POST data argument (void* or char*) */
00263 #define _curl_is_postfields_option(option)                                    \
00264   ((option) == CURLOPT_POSTFIELDS ||                                          \
00265    (option) == CURLOPT_COPYPOSTFIELDS ||                                      \
00266    0)
00267 
00268 /* evaluates to true if option takes a struct curl_slist * argument */
00269 #define _curl_is_slist_option(option)                                         \
00270   ((option) == CURLOPT_HTTPHEADER ||                                          \
00271    (option) == CURLOPT_HTTP200ALIASES ||                                      \
00272    (option) == CURLOPT_QUOTE ||                                               \
00273    (option) == CURLOPT_POSTQUOTE ||                                           \
00274    (option) == CURLOPT_PREQUOTE ||                                            \
00275    (option) == CURLOPT_TELNETOPTIONS ||                                       \
00276    0)
00277 
00278 /* groups of curl_easy_getinfo infos that take the same type of argument */
00279 
00280 /* evaluates to true if info expects a pointer to char * argument */
00281 #define _curl_is_string_info(info)                                            \
00282   (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
00283 
00284 /* evaluates to true if info expects a pointer to long argument */
00285 #define _curl_is_long_info(info)                                              \
00286   (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
00287 
00288 /* evaluates to true if info expects a pointer to double argument */
00289 #define _curl_is_double_info(info)                                            \
00290   (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
00291 
00292 /* true if info expects a pointer to struct curl_slist * argument */
00293 #define _curl_is_slist_info(info)                                             \
00294   (CURLINFO_SLIST < (info))
00295 
00296 
00297 /* typecheck helpers -- check whether given expression has requested type*/
00298 
00299 /* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
00300  * otherwise define a new macro. Search for __builtin_types_compatible_p
00301  * in the GCC manual.
00302  * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
00303  * the actual expression passed to the curl_easy_setopt macro. This
00304  * means that you can only apply the sizeof and __typeof__ operators, no
00305  * == or whatsoever.
00306  */
00307 
00308 /* XXX: should evaluate to true iff expr is a pointer */
00309 #define _curl_is_any_ptr(expr)                                                \
00310   (sizeof(expr) == sizeof(void*))
00311 
00312 /* evaluates to true if expr is NULL */
00313 /* XXX: must not evaluate expr, so this check is not accurate */
00314 #define _curl_is_NULL(expr)                                                   \
00315   (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
00316 
00317 /* evaluates to true if expr is type*, const type* or NULL */
00318 #define _curl_is_ptr(expr, type)                                              \
00319   (_curl_is_NULL(expr) ||                                                     \
00320    __builtin_types_compatible_p(__typeof__(expr), type *) ||                  \
00321    __builtin_types_compatible_p(__typeof__(expr), const type *))
00322 
00323 /* evaluates to true if expr is one of type[], type*, NULL or const type* */
00324 #define _curl_is_arr(expr, type)                                              \
00325   (_curl_is_ptr((expr), type) ||                                              \
00326    __builtin_types_compatible_p(__typeof__(expr), type []))
00327 
00328 /* evaluates to true if expr is a string */
00329 #define _curl_is_string(expr)                                                 \
00330   (_curl_is_arr((expr), char) ||                                              \
00331    _curl_is_arr((expr), signed char) ||                                       \
00332    _curl_is_arr((expr), unsigned char))
00333 
00334 /* evaluates to true if expr is a long (no matter the signedness)
00335  * XXX: for now, int is also accepted (and therefore short and char, which
00336  * are promoted to int when passed to a variadic function) */
00337 #define _curl_is_long(expr)                                                   \
00338   (__builtin_types_compatible_p(__typeof__(expr), long) ||                    \
00339    __builtin_types_compatible_p(__typeof__(expr), signed long) ||             \
00340    __builtin_types_compatible_p(__typeof__(expr), unsigned long) ||           \
00341    __builtin_types_compatible_p(__typeof__(expr), int) ||                     \
00342    __builtin_types_compatible_p(__typeof__(expr), signed int) ||              \
00343    __builtin_types_compatible_p(__typeof__(expr), unsigned int) ||            \
00344    __builtin_types_compatible_p(__typeof__(expr), short) ||                   \
00345    __builtin_types_compatible_p(__typeof__(expr), signed short) ||            \
00346    __builtin_types_compatible_p(__typeof__(expr), unsigned short) ||          \
00347    __builtin_types_compatible_p(__typeof__(expr), char) ||                    \
00348    __builtin_types_compatible_p(__typeof__(expr), signed char) ||             \
00349    __builtin_types_compatible_p(__typeof__(expr), unsigned char))
00350 
00351 /* evaluates to true if expr is of type curl_off_t */
00352 #define _curl_is_off_t(expr)                                                  \
00353   (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
00354 
00355 /* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
00356 /* XXX: also check size of an char[] array? */
00357 #define _curl_is_error_buffer(expr)                                           \
00358   (__builtin_types_compatible_p(__typeof__(expr), char *) ||                  \
00359    __builtin_types_compatible_p(__typeof__(expr), char[]))
00360 
00361 /* evaluates to true if expr is of type (const) void* or (const) FILE* */
00362 #if 0
00363 #define _curl_is_cb_data(expr)                                                \
00364   (_curl_is_ptr((expr), void) ||                                              \
00365    _curl_is_ptr((expr), FILE))
00366 #else /* be less strict */
00367 #define _curl_is_cb_data(expr)                                                \
00368   _curl_is_any_ptr(expr)
00369 #endif
00370 
00371 /* evaluates to true if expr is of type FILE* */
00372 #define _curl_is_FILE(expr)                                                   \
00373   (__builtin_types_compatible_p(__typeof__(expr), FILE *))
00374 
00375 /* evaluates to true if expr can be passed as POST data (void* or char*) */
00376 #define _curl_is_postfields(expr)                                             \
00377   (_curl_is_ptr((expr), void) ||                                              \
00378    _curl_is_arr((expr), char))
00379 
00380 /* FIXME: the whole callback checking is messy...
00381  * The idea is to tolerate char vs. void and const vs. not const
00382  * pointers in arguments at least
00383  */
00384 /* helper: __builtin_types_compatible_p distinguishes between functions and
00385  * function pointers, hide it */
00386 #define _curl_callback_compatible(func, type)                                 \
00387   (__builtin_types_compatible_p(__typeof__(func), type) ||                    \
00388    __builtin_types_compatible_p(__typeof__(func), type*))
00389 
00390 /* evaluates to true if expr is of type curl_read_callback or "similar" */
00391 #define _curl_is_read_cb(expr)                                          \
00392   (_curl_is_NULL(expr) ||                                                     \
00393    __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) ||       \
00394    __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) ||      \
00395    _curl_callback_compatible((expr), _curl_read_callback1) ||                 \
00396    _curl_callback_compatible((expr), _curl_read_callback2) ||                 \
00397    _curl_callback_compatible((expr), _curl_read_callback3) ||                 \
00398    _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
00399    _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
00400    _curl_callback_compatible((expr), _curl_read_callback6))
00401 typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
00402 typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
00403 typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
00404 typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
00405 typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
00406 typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
00407 
00408 /* evaluates to true if expr is of type curl_write_callback or "similar" */
00409 #define _curl_is_write_cb(expr)                                               \
00410   (_curl_is_read_cb(expr) ||                                            \
00411    __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) ||      \
00412    __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) ||     \
00413    _curl_callback_compatible((expr), _curl_write_callback1) ||                \
00414    _curl_callback_compatible((expr), _curl_write_callback2) ||                \
00415    _curl_callback_compatible((expr), _curl_write_callback3) ||                \
00416    _curl_callback_compatible((expr), _curl_write_callback4) ||                \
00417    _curl_callback_compatible((expr), _curl_write_callback5) ||                \
00418    _curl_callback_compatible((expr), _curl_write_callback6))
00419 typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
00420 typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
00421                                        const void*);
00422 typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
00423 typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
00424 typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
00425                                        const void*);
00426 typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
00427 
00428 /* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
00429 #define _curl_is_ioctl_cb(expr)                                         \
00430   (_curl_is_NULL(expr) ||                                                     \
00431    __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) ||     \
00432    _curl_callback_compatible((expr), _curl_ioctl_callback1) ||                \
00433    _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
00434    _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
00435    _curl_callback_compatible((expr), _curl_ioctl_callback4))
00436 typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
00437 typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
00438 typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
00439 typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
00440 
00441 /* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
00442 #define _curl_is_sockopt_cb(expr)                                       \
00443   (_curl_is_NULL(expr) ||                                                     \
00444    __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) ||   \
00445    _curl_callback_compatible((expr), _curl_sockopt_callback1) ||              \
00446    _curl_callback_compatible((expr), _curl_sockopt_callback2))
00447 typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
00448 typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
00449                                       curlsocktype);
00450 
00451 /* evaluates to true if expr is of type curl_opensocket_callback or "similar" */
00452 #define _curl_is_opensocket_cb(expr)                                    \
00453   (_curl_is_NULL(expr) ||                                                     \
00454    __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
00455    _curl_callback_compatible((expr), _curl_opensocket_callback1) ||           \
00456    _curl_callback_compatible((expr), _curl_opensocket_callback2) ||           \
00457    _curl_callback_compatible((expr), _curl_opensocket_callback3) ||           \
00458    _curl_callback_compatible((expr), _curl_opensocket_callback4))
00459 typedef curl_socket_t (_curl_opensocket_callback1)
00460   (void *, curlsocktype, struct curl_sockaddr *);
00461 typedef curl_socket_t (_curl_opensocket_callback2)
00462   (void *, curlsocktype, const struct curl_sockaddr *);
00463 typedef curl_socket_t (_curl_opensocket_callback3)
00464   (const void *, curlsocktype, struct curl_sockaddr *);
00465 typedef curl_socket_t (_curl_opensocket_callback4)
00466   (const void *, curlsocktype, const struct curl_sockaddr *);
00467 
00468 /* evaluates to true if expr is of type curl_progress_callback or "similar" */
00469 #define _curl_is_progress_cb(expr)                                      \
00470   (_curl_is_NULL(expr) ||                                                     \
00471    __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) ||  \
00472    _curl_callback_compatible((expr), _curl_progress_callback1) ||             \
00473    _curl_callback_compatible((expr), _curl_progress_callback2))
00474 typedef int (_curl_progress_callback1)(void *,
00475     double, double, double, double);
00476 typedef int (_curl_progress_callback2)(const void *,
00477     double, double, double, double);
00478 
00479 /* evaluates to true if expr is of type curl_debug_callback or "similar" */
00480 #define _curl_is_debug_cb(expr)                                         \
00481   (_curl_is_NULL(expr) ||                                                     \
00482    __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) ||     \
00483    _curl_callback_compatible((expr), _curl_debug_callback1) ||                \
00484    _curl_callback_compatible((expr), _curl_debug_callback2) ||                \
00485    _curl_callback_compatible((expr), _curl_debug_callback3) ||                \
00486    _curl_callback_compatible((expr), _curl_debug_callback4))
00487 typedef int (_curl_debug_callback1) (CURL *,
00488     curl_infotype, char *, size_t, void *);
00489 typedef int (_curl_debug_callback2) (CURL *,
00490     curl_infotype, char *, size_t, const void *);
00491 typedef int (_curl_debug_callback3) (CURL *,
00492     curl_infotype, const char *, size_t, void *);
00493 typedef int (_curl_debug_callback4) (CURL *,
00494     curl_infotype, const char *, size_t, const void *);
00495 
00496 /* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
00497 /* this is getting even messier... */
00498 #define _curl_is_ssl_ctx_cb(expr)                                       \
00499   (_curl_is_NULL(expr) ||                                                     \
00500    __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) ||   \
00501    _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) ||              \
00502    _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) ||              \
00503    _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) ||              \
00504    _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) ||              \
00505    _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) ||              \
00506    _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) ||              \
00507    _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) ||              \
00508    _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
00509 typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *);
00510 typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
00511 typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
00512 typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
00513 #ifdef HEADER_SSL_H
00514 /* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
00515  * this will of course break if we're included before OpenSSL headers...
00516  */
00517 typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
00518 typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
00519 typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
00520 typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, const void *);
00521 #else
00522 typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
00523 typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
00524 typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
00525 typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
00526 #endif
00527 
00528 /* evaluates to true if expr is of type curl_conv_callback or "similar" */
00529 #define _curl_is_conv_cb(expr)                                          \
00530   (_curl_is_NULL(expr) ||                                                     \
00531    __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) ||      \
00532    _curl_callback_compatible((expr), _curl_conv_callback1) ||                 \
00533    _curl_callback_compatible((expr), _curl_conv_callback2) ||                 \
00534    _curl_callback_compatible((expr), _curl_conv_callback3) ||                 \
00535    _curl_callback_compatible((expr), _curl_conv_callback4))
00536 typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
00537 typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
00538 typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
00539 typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
00540 
00541 /* evaluates to true if expr is of type curl_seek_callback or "similar" */
00542 #define _curl_is_seek_cb(expr)                                          \
00543   (_curl_is_NULL(expr) ||                                                     \
00544    __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) ||      \
00545    _curl_callback_compatible((expr), _curl_seek_callback1) ||                 \
00546    _curl_callback_compatible((expr), _curl_seek_callback2))
00547 typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
00548 typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
00549 
00550 
00551 #endif /* __CURL_TYPECHECK_GCC_H */