aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2008-03-18 08:14:37 +0000
committerMichal Marek <mmarek@suse.cz>2008-03-18 08:14:37 +0000
commit6f3166c15b7fc951b10ba7cb2607527065264f0e (patch)
tree760f1801948bc99fbf7efa645ad101926d81b804
parent1380c9af9fdcd915625dad2fbe3f5676c9bc105f (diff)
- Added curl_easy_getinfo typechecker.
- Added macros for curl_share_setopt and curl_multi_setopt to check at least the correct number of arguments.
-rw-r--r--CHANGES6
-rw-r--r--RELEASE-NOTES9
-rw-r--r--include/curl/curl.h7
-rw-r--r--include/curl/typecheck-gcc.h75
-rw-r--r--lib/easy.c1
-rw-r--r--lib/multi.c1
-rw-r--r--lib/share.c1
7 files changed, 85 insertions, 15 deletions
diff --git a/CHANGES b/CHANGES
index 4a424581f..f8245c6b2 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,12 @@
Changelog
+Michal Marek (18 Mar 2008)
+- Added curl_easy_getinfo typechecker.
+
+- Added macros for curl_share_setopt and curl_multi_setopt to check at least
+ the correct number of arguments.
+
Daniel Fandrich (13 Mar 2008)
- Added tests 622-625 to test SFTP/SCP uploads. Test 625 was an attempt to
reproduce the --ftp-create-dirs problem reported by Brian Ulm, but that
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 02d4c36ed..64e13b642 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -17,10 +17,11 @@ This release includes the following changes:
o the test509-style setting URL in callback is officially no longer supported
o support a full chain of certificates in a given PKCS12 certificate
o resumed transfers work with SFTP
- o added a type checking macro for curl_easy_setopt(), watch out for new
- warnings in code using libcurl (needs gcc-4.3 and currently only works
- in C mode)
- o curl_easy_setopt() uses are now checked to use three arguments
+ o added type checking macros for curl_easy_setopt() and curl_easy_getinfo(),
+ watch out for new warnings in code using libcurl (needs gcc-4.3 and
+ currently only works in C mode)
+ o curl_easy_setopt(), curl_easy_getinfo(), curl_share_setopt() and
+ curl_multi_setopt() uses are now checked to use exactly three arguments
This release includes the following bugfixes:
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 4af714291..b4ed5d0f0 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -1798,9 +1798,12 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
#else
#if defined(__STDC__) && (__STDC__ >= 1)
/* This preprocessor magic that replaces a call with the exact same call is
- only done to make sure application authors use exactly three arguments
- to this function. */
+ only done to make sure application authors pass exactly three arguments
+ to these functions. */
#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
+#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
#endif /* __STDC__ >= 1 */
#endif /* gcc >= 4.3 && !__cplusplus */
diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h
index c6475b735..969e2bbe4 100644
--- a/include/curl/typecheck-gcc.h
+++ b/include/curl/typecheck-gcc.h
@@ -76,10 +76,10 @@ __extension__ ({ \
if (_curl_is_postfields_option(_curl_opt) && !_curl_is_postfields(value)) \
_curl_easy_setopt_err_postfields(); \
if ((_curl_opt) == CURLOPT_HTTPPOST && \
- !_curl_is_ptr((value), struct curl_httppost)) \
+ !_curl_is_arr((value), struct curl_httppost)) \
_curl_easy_setopt_err_curl_httpost(); \
if (_curl_is_slist_option(_curl_opt) && \
- !_curl_is_ptr((value), struct curl_slist)) \
+ !_curl_is_arr((value), struct curl_slist)) \
_curl_easy_setopt_err_curl_slist(); \
if ((_curl_opt) == CURLOPT_SHARE && !_curl_is_ptr((value), CURLSH)) \
_curl_easy_setopt_err_CURLSH(); \
@@ -87,10 +87,37 @@ __extension__ ({ \
curl_easy_setopt(handle, _curl_opt, value); \
})
+/* wraps curl_easy_getinfo() with typechecking */
+/* FIXME: don't allow const pointers */
+#define curl_easy_getinfo(handle, info, arg) \
+__extension__ ({ \
+ __typeof__ (info) _curl_info = info; \
+ if (__builtin_constant_p(_curl_info)) { \
+ if (_curl_is_string_info(_curl_info) && !_curl_is_arr((arg), char *)) \
+ _curl_easy_getinfo_err_string(); \
+ if (_curl_is_long_info(_curl_info) && !_curl_is_arr((arg), long)) \
+ _curl_easy_getinfo_err_long(); \
+ if (_curl_is_double_info(_curl_info) && !_curl_is_arr((arg), double)) \
+ _curl_easy_getinfo_err_double(); \
+ if (_curl_is_slist_info(_curl_info) && \
+ !_curl_is_arr((arg), struct curl_slist *)) \
+ _curl_easy_getinfo_err_curl_slist(); \
+ } \
+ curl_easy_getinfo(handle, _curl_info, arg); \
+})
+
+/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
+ * for now just make sure that the functions are called with three
+ * arguments
+ */
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
+
/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
* functions */
-/* To define a new warning, use _CURL_WARNING(identifier, "message"); */
+/* To define a new warning, use _CURL_WARNING(identifier, "message") */
#define _CURL_WARNING(id, message) \
static void __attribute__((warning(message))) __attribute__((unused)) \
__attribute__((noinline)) id(void) { __asm__(""); }
@@ -136,7 +163,16 @@ _CURL_WARNING(_curl_easy_setopt_err_curl_slist,
_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
"curl_easy_setopt expects a CURLSH* argument for this option")
-/* groups of options that take the same type of argument */
+_CURL_WARNING(_curl_easy_getinfo_err_string,
+ "curl_easy_getinfo expects a pointer to char * for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_long,
+ "curl_easy_getinfo expects a pointer to long for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_double,
+ "curl_easy_getinfo expects a pointer to double for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
+ "curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
+
+/* groups of curl_easy_setops options that take the same type of argument */
/* To add a new option to one of the groups, just add
* (option) == CURLOPT_SOMETHING
@@ -230,13 +266,34 @@ _CURL_WARNING(_curl_easy_setopt_err_CURLSH,
(option) == CURLOPT_TELNETOPTIONS || \
0)
+/* groups of curl_easy_getinfo infos that take the same type of argument */
+
+/* evaluates to true if info expects a pointer to char * argument */
+#define _curl_is_string_info(info) \
+ (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
+
+/* evaluates to true if info expects a pointer to long argument */
+#define _curl_is_long_info(info) \
+ (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
+
+/* evaluates to true if info expects a pointer to double argument */
+#define _curl_is_double_info(info) \
+ (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
+
+/* evaluates to true if info expects a pointer to struct curl_slist * argument */
+#define _curl_is_slist_info(info) \
+ (CURLINFO_SLIST < (info))
+
+
/* typecheck helpers -- check whether given expression has requested type*/
-/* For pointers, you can use the _curl_is_ptr macro, otherwise define a new
- * macro. Search for __builtin_types_compatible_p in the GCC manual. NOTE:
- * these macros MUST NOT EVALUATE their arguments! The argument is the actual
- * expression passed to the curl_easy_setopt macro. This means that you can
- * only apply the sizeof and __typeof__ operators, no == or whatsoever.
+/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
+ * otherwise define a new macro. Search for __builtin_types_compatible_p
+ * in the GCC manual.
+ * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
+ * the actual expression passed to the curl_easy_setopt macro. This
+ * means that you can only apply the sizeof and __typeof__ operators, no
+ * == or whatsoever.
*/
/* XXX: should evaluate to true iff expr is a pointer */
diff --git a/lib/easy.c b/lib/easy.c
index 018aeab6e..cfa6c41b1 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -548,6 +548,7 @@ void Curl_easy_initHandleData(struct SessionHandle *data)
* curl_easy_getinfo() is an external interface that allows an app to retrieve
* information from a performed transfer and similar.
*/
+#undef curl_easy_getinfo
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
{
va_list arg;
diff --git a/lib/multi.c b/lib/multi.c
index a29b6a0ae..73e8e7e3d 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1778,6 +1778,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
return result;
}
+#undef curl_multi_setopt
CURLMcode curl_multi_setopt(CURLM *multi_handle,
CURLMoption option, ...)
{
diff --git a/lib/share.c b/lib/share.c
index eb2ee78ce..3a5f072bd 100644
--- a/lib/share.c
+++ b/lib/share.c
@@ -46,6 +46,7 @@ curl_share_init(void)
return share;
}
+#undef curl_share_setopt
CURLSHcode
curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
{