PageRenderTime 53ms CodeModel.GetById 8ms app.highlight 36ms RepoModel.GetById 2ms app.codeStats 0ms

/thirdparty/breakpad/third_party/curl/typecheck-gcc.h

http://github.com/tomahawk-player/tomahawk
C++ Header | 551 lines | 397 code | 51 blank | 103 comment | 266 complexity | 9bac2be854e3137609ef1c4dbd957386 MD5 | raw file
  1#ifndef __CURL_TYPECHECK_GCC_H
  2#define __CURL_TYPECHECK_GCC_H
  3/***************************************************************************
  4 *                                  _   _ ____  _
  5 *  Project                     ___| | | |  _ \| |
  6 *                             / __| | | | |_) | |
  7 *                            | (__| |_| |  _ <| |___
  8 *                             \___|\___/|_| \_\_____|
  9 *
 10 * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
 11 *
 12 * This software is licensed as described in the file COPYING, which
 13 * you should have received as part of this distribution. The terms
 14 * are also available at http://curl.haxx.se/docs/copyright.html.
 15 *
 16 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 17 * copies of the Software, and permit persons to whom the Software is
 18 * furnished to do so, under the terms of the COPYING file.
 19 *
 20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 21 * KIND, either express or implied.
 22 *
 23 * $Id: typecheck-gcc.h,v 1.9 2009-01-25 23:26:31 bagder Exp $
 24 ***************************************************************************/
 25
 26/* wraps curl_easy_setopt() with typechecking */
 27
 28/* To add a new kind of warning, add an
 29 *   if(_curl_is_sometype_option(_curl_opt) && ! _curl_is_sometype(value))
 30 *     _curl_easy_setopt_err_sometype();
 31 * block and define _curl_is_sometype_option, _curl_is_sometype and
 32 * _curl_easy_setopt_err_sometype below
 33 *
 34 * To add an option that uses the same type as an existing option, you'll just
 35 * need to extend the appropriate _curl_*_option macro
 36 */
 37#define curl_easy_setopt(handle, option, value)                               \
 38__extension__ ({                                                              \
 39  __typeof__ (option) _curl_opt = option;                                     \
 40  if (__builtin_constant_p(_curl_opt)) {                                      \
 41    if (_curl_is_long_option(_curl_opt) && !_curl_is_long(value))             \
 42      _curl_easy_setopt_err_long();                                           \
 43    if (_curl_is_off_t_option(_curl_opt) && !_curl_is_off_t(value))           \
 44      _curl_easy_setopt_err_curl_off_t();                                     \
 45    if (_curl_is_string_option(_curl_opt) && !_curl_is_string(value))         \
 46      _curl_easy_setopt_err_string();                                         \
 47    if (_curl_is_write_cb_option(_curl_opt) && !_curl_is_write_cb(value))     \
 48      _curl_easy_setopt_err_write_callback();                                 \
 49    if ((_curl_opt) == CURLOPT_READFUNCTION && !_curl_is_read_cb(value))      \
 50      _curl_easy_setopt_err_read_cb();                                        \
 51    if ((_curl_opt) == CURLOPT_IOCTLFUNCTION && !_curl_is_ioctl_cb(value))    \
 52      _curl_easy_setopt_err_ioctl_cb();                                       \
 53    if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION && !_curl_is_sockopt_cb(value))\
 54      _curl_easy_setopt_err_sockopt_cb();                                     \
 55    if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION &&                          \
 56            !_curl_is_opensocket_cb(value))                                   \
 57      _curl_easy_setopt_err_opensocket_cb();                                  \
 58    if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION &&                            \
 59            !_curl_is_progress_cb(value))                                     \
 60      _curl_easy_setopt_err_progress_cb();                                    \
 61    if ((_curl_opt) == CURLOPT_DEBUGFUNCTION && !_curl_is_debug_cb(value))    \
 62      _curl_easy_setopt_err_debug_cb();                                       \
 63    if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION &&                            \
 64            !_curl_is_ssl_ctx_cb(value))                                      \
 65      _curl_easy_setopt_err_ssl_ctx_cb();                                     \
 66    if (_curl_is_conv_cb_option(_curl_opt) && !_curl_is_conv_cb(value))       \
 67      _curl_easy_setopt_err_conv_cb();                                        \
 68    if ((_curl_opt) == CURLOPT_SEEKFUNCTION && !_curl_is_seek_cb(value))      \
 69      _curl_easy_setopt_err_seek_cb();                                        \
 70    if (_curl_is_cb_data_option(_curl_opt) && !_curl_is_cb_data(value))       \
 71      _curl_easy_setopt_err_cb_data();                                        \
 72    if ((_curl_opt) == CURLOPT_ERRORBUFFER && !_curl_is_error_buffer(value))  \
 73      _curl_easy_setopt_err_error_buffer();                                   \
 74    if ((_curl_opt) == CURLOPT_STDERR && !_curl_is_FILE(value))               \
 75      _curl_easy_setopt_err_FILE();                                           \
 76    if (_curl_is_postfields_option(_curl_opt) && !_curl_is_postfields(value)) \
 77      _curl_easy_setopt_err_postfields();                                     \
 78    if ((_curl_opt) == CURLOPT_HTTPPOST &&                                    \
 79            !_curl_is_arr((value), struct curl_httppost))                     \
 80      _curl_easy_setopt_err_curl_httpost();                                   \
 81    if (_curl_is_slist_option(_curl_opt) &&                                   \
 82            !_curl_is_arr((value), struct curl_slist))                        \
 83      _curl_easy_setopt_err_curl_slist();                                     \
 84    if ((_curl_opt) == CURLOPT_SHARE && !_curl_is_ptr((value), CURLSH))       \
 85      _curl_easy_setopt_err_CURLSH();                                         \
 86  }                                                                           \
 87  curl_easy_setopt(handle, _curl_opt, value);                                 \
 88})
 89
 90/* wraps curl_easy_getinfo() with typechecking */
 91/* FIXME: don't allow const pointers */
 92#define curl_easy_getinfo(handle, info, arg)                                  \
 93__extension__ ({                                                              \
 94  __typeof__ (info) _curl_info = info;                                        \
 95  if (__builtin_constant_p(_curl_info)) {                                     \
 96    if (_curl_is_string_info(_curl_info) && !_curl_is_arr((arg), char *))     \
 97      _curl_easy_getinfo_err_string();                                        \
 98    if (_curl_is_long_info(_curl_info) && !_curl_is_arr((arg), long))         \
 99      _curl_easy_getinfo_err_long();                                          \
100    if (_curl_is_double_info(_curl_info) && !_curl_is_arr((arg), double))     \
101      _curl_easy_getinfo_err_double();                                        \
102    if (_curl_is_slist_info(_curl_info) &&                                    \
103           !_curl_is_arr((arg), struct curl_slist *))                         \
104      _curl_easy_getinfo_err_curl_slist();                                    \
105  }                                                                           \
106  curl_easy_getinfo(handle, _curl_info, arg);                                 \
107})
108
109/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
110 * for now just make sure that the functions are called with three
111 * arguments
112 */
113#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
114#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
115
116
117/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
118 * functions */
119
120/* To define a new warning, use _CURL_WARNING(identifier, "message") */
121#define _CURL_WARNING(id, message)                                            \
122  static void __attribute__((warning(message))) __attribute__((unused))       \
123  __attribute__((noinline)) id(void) { __asm__(""); }
124
125_CURL_WARNING(_curl_easy_setopt_err_long,
126  "curl_easy_setopt expects a long argument for this option")
127_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
128  "curl_easy_setopt expects a curl_off_t argument for this option")
129_CURL_WARNING(_curl_easy_setopt_err_string,
130  "curl_easy_setopt expects a string (char* or char[]) argument for this option"
131  )
132_CURL_WARNING(_curl_easy_setopt_err_write_callback,
133  "curl_easy_setopt expects a curl_write_callback argument for this option")
134_CURL_WARNING(_curl_easy_setopt_err_read_cb,
135  "curl_easy_setopt expects a curl_read_callback argument for this option")
136_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
137  "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
138_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
139  "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
140_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
141  "curl_easy_setopt expects a curl_opensocket_callback argument for this option"
142  )
143_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
144  "curl_easy_setopt expects a curl_progress_callback argument for this option")
145_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
146  "curl_easy_setopt expects a curl_debug_callback argument for this option")
147_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
148  "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
149_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
150  "curl_easy_setopt expects a curl_conv_callback argument for this option")
151_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
152  "curl_easy_setopt expects a curl_seek_callback argument for this option")
153_CURL_WARNING(_curl_easy_setopt_err_cb_data,
154  "curl_easy_setopt expects a private data pointer as argument for this option")
155_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
156  "curl_easy_setopt expects a char buffer of CURL_ERROR_SIZE as argument for this option")
157_CURL_WARNING(_curl_easy_setopt_err_FILE,
158  "curl_easy_setopt expects a FILE* argument for this option")
159_CURL_WARNING(_curl_easy_setopt_err_postfields,
160  "curl_easy_setopt expects a void* or char* argument for this option")
161_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
162  "curl_easy_setopt expects a struct curl_httppost* argument for this option")
163_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
164  "curl_easy_setopt expects a struct curl_slist* argument for this option")
165_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
166  "curl_easy_setopt expects a CURLSH* argument for this option")
167
168_CURL_WARNING(_curl_easy_getinfo_err_string,
169  "curl_easy_getinfo expects a pointer to char * for this info")
170_CURL_WARNING(_curl_easy_getinfo_err_long,
171  "curl_easy_getinfo expects a pointer to long for this info")
172_CURL_WARNING(_curl_easy_getinfo_err_double,
173  "curl_easy_getinfo expects a pointer to double for this info")
174_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
175  "curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
176
177/* groups of curl_easy_setops options that take the same type of argument */
178
179/* To add a new option to one of the groups, just add
180 *   (option) == CURLOPT_SOMETHING
181 * to the or-expression. If the option takes a long or curl_off_t, you don't
182 * have to do anything
183 */
184
185/* evaluates to true if option takes a long argument */
186#define _curl_is_long_option(option)                                          \
187  (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
188
189#define _curl_is_off_t_option(option)                                         \
190  ((option) > CURLOPTTYPE_OFF_T)
191
192/* evaluates to true if option takes a char* argument */
193#define _curl_is_string_option(option)                                        \
194  ((option) == CURLOPT_URL ||                                                 \
195   (option) == CURLOPT_PROXY ||                                               \
196   (option) == CURLOPT_INTERFACE ||                                           \
197   (option) == CURLOPT_NETRC_FILE ||                                          \
198   (option) == CURLOPT_USERPWD ||                                             \
199   (option) == CURLOPT_USERNAME ||                                            \
200   (option) == CURLOPT_PASSWORD ||                                            \
201   (option) == CURLOPT_PROXYUSERPWD ||                                        \
202   (option) == CURLOPT_PROXYUSERNAME ||                                       \
203   (option) == CURLOPT_PROXYPASSWORD ||                                       \
204   (option) == CURLOPT_NOPROXY ||                                             \
205   (option) == CURLOPT_ENCODING ||                                            \
206   (option) == CURLOPT_REFERER ||                                             \
207   (option) == CURLOPT_USERAGENT ||                                           \
208   (option) == CURLOPT_COOKIE ||                                              \
209   (option) == CURLOPT_COOKIEFILE ||                                          \
210   (option) == CURLOPT_COOKIEJAR ||                                           \
211   (option) == CURLOPT_COOKIELIST ||                                          \
212   (option) == CURLOPT_FTPPORT ||                                             \
213   (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                             \
214   (option) == CURLOPT_FTP_ACCOUNT ||                                         \
215   (option) == CURLOPT_RANGE ||                                               \
216   (option) == CURLOPT_CUSTOMREQUEST ||                                       \
217   (option) == CURLOPT_SSLCERT ||                                             \
218   (option) == CURLOPT_SSLCERTTYPE ||                                         \
219   (option) == CURLOPT_SSLKEY ||                                              \
220   (option) == CURLOPT_SSLKEYTYPE ||                                          \
221   (option) == CURLOPT_KEYPASSWD ||                                           \
222   (option) == CURLOPT_SSLENGINE ||                                           \
223   (option) == CURLOPT_CAINFO ||                                              \
224   (option) == CURLOPT_CAPATH ||                                              \
225   (option) == CURLOPT_RANDOM_FILE ||                                         \
226   (option) == CURLOPT_EGDSOCKET ||                                           \
227   (option) == CURLOPT_SSL_CIPHER_LIST ||                                     \
228   (option) == CURLOPT_KRBLEVEL ||                                            \
229   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
230   (option) == CURLOPT_SSH_PUBLIC_KEYFILE ||                                  \
231   (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                                 \
232   (option) == CURLOPT_CRLFILE ||                                             \
233   (option) == CURLOPT_ISSUERCERT ||                                          \
234   0)
235
236/* evaluates to true if option takes a curl_write_callback argument */
237#define _curl_is_write_cb_option(option)                                      \
238  ((option) == CURLOPT_HEADERFUNCTION ||                                      \
239   (option) == CURLOPT_WRITEFUNCTION)
240
241/* evaluates to true if option takes a curl_conv_callback argument */
242#define _curl_is_conv_cb_option(option)                                       \
243  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                            \
244   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                          \
245   (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
246
247/* evaluates to true if option takes a data argument to pass to a callback */
248#define _curl_is_cb_data_option(option)                                       \
249  ((option) == CURLOPT_WRITEDATA ||                                           \
250   (option) == CURLOPT_READDATA ||                                            \
251   (option) == CURLOPT_IOCTLDATA ||                                           \
252   (option) == CURLOPT_SOCKOPTDATA ||                                         \
253   (option) == CURLOPT_OPENSOCKETDATA ||                                      \
254   (option) == CURLOPT_PROGRESSDATA ||                                        \
255   (option) == CURLOPT_WRITEHEADER ||                                         \
256   (option) == CURLOPT_DEBUGDATA ||                                           \
257   (option) == CURLOPT_SSL_CTX_DATA ||                                        \
258   (option) == CURLOPT_SEEKDATA ||                                            \
259   (option) == CURLOPT_PRIVATE ||                                             \
260   0)
261
262/* evaluates to true if option takes a POST data argument (void* or char*) */
263#define _curl_is_postfields_option(option)                                    \
264  ((option) == CURLOPT_POSTFIELDS ||                                          \
265   (option) == CURLOPT_COPYPOSTFIELDS ||                                      \
266   0)
267
268/* evaluates to true if option takes a struct curl_slist * argument */
269#define _curl_is_slist_option(option)                                         \
270  ((option) == CURLOPT_HTTPHEADER ||                                          \
271   (option) == CURLOPT_HTTP200ALIASES ||                                      \
272   (option) == CURLOPT_QUOTE ||                                               \
273   (option) == CURLOPT_POSTQUOTE ||                                           \
274   (option) == CURLOPT_PREQUOTE ||                                            \
275   (option) == CURLOPT_TELNETOPTIONS ||                                       \
276   0)
277
278/* groups of curl_easy_getinfo infos that take the same type of argument */
279
280/* evaluates to true if info expects a pointer to char * argument */
281#define _curl_is_string_info(info)                                            \
282  (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
283
284/* evaluates to true if info expects a pointer to long argument */
285#define _curl_is_long_info(info)                                              \
286  (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
287
288/* evaluates to true if info expects a pointer to double argument */
289#define _curl_is_double_info(info)                                            \
290  (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
291
292/* true if info expects a pointer to struct curl_slist * argument */
293#define _curl_is_slist_info(info)                                             \
294  (CURLINFO_SLIST < (info))
295
296
297/* typecheck helpers -- check whether given expression has requested type*/
298
299/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
300 * otherwise define a new macro. Search for __builtin_types_compatible_p
301 * in the GCC manual.
302 * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
303 * the actual expression passed to the curl_easy_setopt macro. This
304 * means that you can only apply the sizeof and __typeof__ operators, no
305 * == or whatsoever.
306 */
307
308/* XXX: should evaluate to true iff expr is a pointer */
309#define _curl_is_any_ptr(expr)                                                \
310  (sizeof(expr) == sizeof(void*))
311
312/* evaluates to true if expr is NULL */
313/* XXX: must not evaluate expr, so this check is not accurate */
314#define _curl_is_NULL(expr)                                                   \
315  (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
316
317/* evaluates to true if expr is type*, const type* or NULL */
318#define _curl_is_ptr(expr, type)                                              \
319  (_curl_is_NULL(expr) ||                                                     \
320   __builtin_types_compatible_p(__typeof__(expr), type *) ||                  \
321   __builtin_types_compatible_p(__typeof__(expr), const type *))
322
323/* evaluates to true if expr is one of type[], type*, NULL or const type* */
324#define _curl_is_arr(expr, type)                                              \
325  (_curl_is_ptr((expr), type) ||                                              \
326   __builtin_types_compatible_p(__typeof__(expr), type []))
327
328/* evaluates to true if expr is a string */
329#define _curl_is_string(expr)                                                 \
330  (_curl_is_arr((expr), char) ||                                              \
331   _curl_is_arr((expr), signed char) ||                                       \
332   _curl_is_arr((expr), unsigned char))
333
334/* evaluates to true if expr is a long (no matter the signedness)
335 * XXX: for now, int is also accepted (and therefore short and char, which
336 * are promoted to int when passed to a variadic function) */
337#define _curl_is_long(expr)                                                   \
338  (__builtin_types_compatible_p(__typeof__(expr), long) ||                    \
339   __builtin_types_compatible_p(__typeof__(expr), signed long) ||             \
340   __builtin_types_compatible_p(__typeof__(expr), unsigned long) ||           \
341   __builtin_types_compatible_p(__typeof__(expr), int) ||                     \
342   __builtin_types_compatible_p(__typeof__(expr), signed int) ||              \
343   __builtin_types_compatible_p(__typeof__(expr), unsigned int) ||            \
344   __builtin_types_compatible_p(__typeof__(expr), short) ||                   \
345   __builtin_types_compatible_p(__typeof__(expr), signed short) ||            \
346   __builtin_types_compatible_p(__typeof__(expr), unsigned short) ||          \
347   __builtin_types_compatible_p(__typeof__(expr), char) ||                    \
348   __builtin_types_compatible_p(__typeof__(expr), signed char) ||             \
349   __builtin_types_compatible_p(__typeof__(expr), unsigned char))
350
351/* evaluates to true if expr is of type curl_off_t */
352#define _curl_is_off_t(expr)                                                  \
353  (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
354
355/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
356/* XXX: also check size of an char[] array? */
357#define _curl_is_error_buffer(expr)                                           \
358  (__builtin_types_compatible_p(__typeof__(expr), char *) ||                  \
359   __builtin_types_compatible_p(__typeof__(expr), char[]))
360
361/* evaluates to true if expr is of type (const) void* or (const) FILE* */
362#if 0
363#define _curl_is_cb_data(expr)                                                \
364  (_curl_is_ptr((expr), void) ||                                              \
365   _curl_is_ptr((expr), FILE))
366#else /* be less strict */
367#define _curl_is_cb_data(expr)                                                \
368  _curl_is_any_ptr(expr)
369#endif
370
371/* evaluates to true if expr is of type FILE* */
372#define _curl_is_FILE(expr)                                                   \
373  (__builtin_types_compatible_p(__typeof__(expr), FILE *))
374
375/* evaluates to true if expr can be passed as POST data (void* or char*) */
376#define _curl_is_postfields(expr)                                             \
377  (_curl_is_ptr((expr), void) ||                                              \
378   _curl_is_arr((expr), char))
379
380/* FIXME: the whole callback checking is messy...
381 * The idea is to tolerate char vs. void and const vs. not const
382 * pointers in arguments at least
383 */
384/* helper: __builtin_types_compatible_p distinguishes between functions and
385 * function pointers, hide it */
386#define _curl_callback_compatible(func, type)                                 \
387  (__builtin_types_compatible_p(__typeof__(func), type) ||                    \
388   __builtin_types_compatible_p(__typeof__(func), type*))
389
390/* evaluates to true if expr is of type curl_read_callback or "similar" */
391#define _curl_is_read_cb(expr)                                          \
392  (_curl_is_NULL(expr) ||                                                     \
393   __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) ||       \
394   __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) ||      \
395   _curl_callback_compatible((expr), _curl_read_callback1) ||                 \
396   _curl_callback_compatible((expr), _curl_read_callback2) ||                 \
397   _curl_callback_compatible((expr), _curl_read_callback3) ||                 \
398   _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
399   _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
400   _curl_callback_compatible((expr), _curl_read_callback6))
401typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
402typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
403typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
404typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
405typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
406typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
407
408/* evaluates to true if expr is of type curl_write_callback or "similar" */
409#define _curl_is_write_cb(expr)                                               \
410  (_curl_is_read_cb(expr) ||                                            \
411   __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) ||      \
412   __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) ||     \
413   _curl_callback_compatible((expr), _curl_write_callback1) ||                \
414   _curl_callback_compatible((expr), _curl_write_callback2) ||                \
415   _curl_callback_compatible((expr), _curl_write_callback3) ||                \
416   _curl_callback_compatible((expr), _curl_write_callback4) ||                \
417   _curl_callback_compatible((expr), _curl_write_callback5) ||                \
418   _curl_callback_compatible((expr), _curl_write_callback6))
419typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
420typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
421                                       const void*);
422typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
423typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
424typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
425                                       const void*);
426typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
427
428/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
429#define _curl_is_ioctl_cb(expr)                                         \
430  (_curl_is_NULL(expr) ||                                                     \
431   __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) ||     \
432   _curl_callback_compatible((expr), _curl_ioctl_callback1) ||                \
433   _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
434   _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
435   _curl_callback_compatible((expr), _curl_ioctl_callback4))
436typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
437typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
438typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
439typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
440
441/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
442#define _curl_is_sockopt_cb(expr)                                       \
443  (_curl_is_NULL(expr) ||                                                     \
444   __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) ||   \
445   _curl_callback_compatible((expr), _curl_sockopt_callback1) ||              \
446   _curl_callback_compatible((expr), _curl_sockopt_callback2))
447typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
448typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t,
449                                      curlsocktype);
450
451/* evaluates to true if expr is of type curl_opensocket_callback or "similar" */
452#define _curl_is_opensocket_cb(expr)                                    \
453  (_curl_is_NULL(expr) ||                                                     \
454   __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
455   _curl_callback_compatible((expr), _curl_opensocket_callback1) ||           \
456   _curl_callback_compatible((expr), _curl_opensocket_callback2) ||           \
457   _curl_callback_compatible((expr), _curl_opensocket_callback3) ||           \
458   _curl_callback_compatible((expr), _curl_opensocket_callback4))
459typedef curl_socket_t (_curl_opensocket_callback1)
460  (void *, curlsocktype, struct curl_sockaddr *);
461typedef curl_socket_t (_curl_opensocket_callback2)
462  (void *, curlsocktype, const struct curl_sockaddr *);
463typedef curl_socket_t (_curl_opensocket_callback3)
464  (const void *, curlsocktype, struct curl_sockaddr *);
465typedef curl_socket_t (_curl_opensocket_callback4)
466  (const void *, curlsocktype, const struct curl_sockaddr *);
467
468/* evaluates to true if expr is of type curl_progress_callback or "similar" */
469#define _curl_is_progress_cb(expr)                                      \
470  (_curl_is_NULL(expr) ||                                                     \
471   __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) ||  \
472   _curl_callback_compatible((expr), _curl_progress_callback1) ||             \
473   _curl_callback_compatible((expr), _curl_progress_callback2))
474typedef int (_curl_progress_callback1)(void *,
475    double, double, double, double);
476typedef int (_curl_progress_callback2)(const void *,
477    double, double, double, double);
478
479/* evaluates to true if expr is of type curl_debug_callback or "similar" */
480#define _curl_is_debug_cb(expr)                                         \
481  (_curl_is_NULL(expr) ||                                                     \
482   __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) ||     \
483   _curl_callback_compatible((expr), _curl_debug_callback1) ||                \
484   _curl_callback_compatible((expr), _curl_debug_callback2) ||                \
485   _curl_callback_compatible((expr), _curl_debug_callback3) ||                \
486   _curl_callback_compatible((expr), _curl_debug_callback4))
487typedef int (_curl_debug_callback1) (CURL *,
488    curl_infotype, char *, size_t, void *);
489typedef int (_curl_debug_callback2) (CURL *,
490    curl_infotype, char *, size_t, const void *);
491typedef int (_curl_debug_callback3) (CURL *,
492    curl_infotype, const char *, size_t, void *);
493typedef int (_curl_debug_callback4) (CURL *,
494    curl_infotype, const char *, size_t, const void *);
495
496/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
497/* this is getting even messier... */
498#define _curl_is_ssl_ctx_cb(expr)                                       \
499  (_curl_is_NULL(expr) ||                                                     \
500   __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) ||   \
501   _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) ||              \
502   _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) ||              \
503   _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) ||              \
504   _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) ||              \
505   _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) ||              \
506   _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) ||              \
507   _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) ||              \
508   _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
509typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *);
510typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
511typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
512typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
513#ifdef HEADER_SSL_H
514/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
515 * this will of course break if we're included before OpenSSL headers...
516 */
517typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
518typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
519typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
520typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, const void *);
521#else
522typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
523typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
524typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
525typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
526#endif
527
528/* evaluates to true if expr is of type curl_conv_callback or "similar" */
529#define _curl_is_conv_cb(expr)                                          \
530  (_curl_is_NULL(expr) ||                                                     \
531   __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) ||      \
532   _curl_callback_compatible((expr), _curl_conv_callback1) ||                 \
533   _curl_callback_compatible((expr), _curl_conv_callback2) ||                 \
534   _curl_callback_compatible((expr), _curl_conv_callback3) ||                 \
535   _curl_callback_compatible((expr), _curl_conv_callback4))
536typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
537typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
538typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
539typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
540
541/* evaluates to true if expr is of type curl_seek_callback or "similar" */
542#define _curl_is_seek_cb(expr)                                          \
543  (_curl_is_NULL(expr) ||                                                     \
544   __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) ||      \
545   _curl_callback_compatible((expr), _curl_seek_callback1) ||                 \
546   _curl_callback_compatible((expr), _curl_seek_callback2))
547typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
548typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
549
550
551#endif /* __CURL_TYPECHECK_GCC_H */