Browse Source

OS400: improve vararg emulation

- Use V7R4 RPG procedure overloading to improve vararg emulation.

From OS400 V7R4 and above, ILE/RPG implements a limited procedure
overloading feature that can be used to improve curl's typed
implementation of varargs procedures. This commit applies it to
curl_easy_setopt(), curl_multi_setopt(), curl_share_setopt() and
curl_easy_getinfo().

Closes https://github.com/curl/curl/pull/10994
Patrick Monnerat 1 year ago
parent
commit
59ce2620a9
4 changed files with 76 additions and 0 deletions
  1. 4 0
      packages/OS400/README.OS400
  2. 23 0
      packages/OS400/ccsidcurl.c
  3. 4 0
      packages/OS400/ccsidcurl.h
  4. 45 0
      packages/OS400/curl.inc.in

+ 4 - 0
packages/OS400/README.OS400

@@ -376,6 +376,10 @@ _ The prototype of procedure curl_formadd() allows specifying a pointer option
   without any additional definition. If some specific incompatible argument
   list is used in the ILE/RPG program, the latter must define a specialised
   alias. The same applies to curl_formadd_ccsid() too.
+_ Since V7R4M0, procedure overloading is used to emulate limited "vararg-like"
+  definitions of curl_easy_setopt(), curl_multi_setopt(), curl_share_setopt()
+  and curl_easy_getinfo(). Blob and CCSID alternatives are NOT included in
+  overloading.
 
   Since RPG cannot cast a long to a pointer, procedure curl_form_long_value()
 is provided for that purpose: this allows storing a long value in the

+ 23 - 0
packages/OS400/ccsidcurl.c

@@ -1299,6 +1299,29 @@ curl_form_long_value(long value)
 }
 
 
+CURLcode
+curl_easy_setopt_RPGnum_(CURL *easy, CURLoption tag, curl_off_t arg)
+{
+  /* ILE/RPG procedure overloading cannot discriminate between different
+     size and/or signedness of format arguments. This provides a generic
+     wrapper that adapts size to the given tag expectation.
+     This procedure is not intended to be explicitly called from user code. */
+  if(tag / 10000 != CURLOPTTYPE_OFF_T)
+    return curl_easy_setopt(easy, tag, (long) arg);
+  return curl_easy_setopt(easy, tag, arg);
+}
+
+
+CURLcode
+curl_multi_setopt_RPGnum_(CURLM *multi, CURLMoption tag, curl_off_t arg)
+{
+  /* Likewise, for multi handle. */
+  if(tag / 10000 != CURLOPTTYPE_OFF_T)
+    return curl_multi_setopt(multi, tag, (long) arg);
+  return curl_multi_setopt(multi, tag, arg);
+}
+
+
 char *
 curl_pushheader_bynum_cssid(struct curl_pushheaders *h,
                             size_t num, unsigned int ccsid)

+ 4 - 0
packages/OS400/ccsidcurl.h

@@ -105,5 +105,9 @@ CURL_EXTERN CURLHcode curl_easy_header_ccsid(CURL *easy, const char *name,
                                              unsigned int ccsid);
 CURL_EXTERN const char *curl_from_ccsid(const char *s, unsigned int ccsid);
 CURL_EXTERN const char *curl_to_ccsid(const char *s, unsigned int ccsid);
+CURL_EXTERN CURLcode curl_easy_setopt_RPGnum_(CURL *easy,
+                                              CURLoption tag, curl_off_t arg);
+CURL_EXTERN CURLcode curl_multi_setopt_RPGnum_(CURLM *multi, CURLMoption tag,
+                                               curl_off_t arg);
 
 #endif

+ 45 - 0
packages/OS400/curl.inc.in

@@ -3358,5 +3358,50 @@
      d                 pr              *   extproc('curl_to_ccsid')             const char *
      d  s                              *   value options(*string)               const char *
      d  ccsid                        10u 0 value
+      *
+      **************************************************************************
+      *                       Procedure overloading
+      **************************************************************************
+      *
+      /if defined(*V7R4M0)
+     d curl_easy_setopt_RPGnum_...
+     d                 pr                  extproc('curl_easy_setopt_RPGnum_')
+     d                                     like(CURLcode)
+     d  curl                           *   value                                CURL *
+     d  option                             value like(CURLoption)
+     d  numarg                       20i 0 value
+      *
+     d curl_easy_setopt...
+     d                 pr                  like(CURLcode)
+     d                                     overload(curl_easy_setopt_RPGnum_:
+     d                                              curl_easy_setopt_object:
+     d                                              curl_easy_setopt_function)
+      *
+     d curl_multi_setopt_RPGnum_...
+     d                 pr                  extproc('curl_multi_setopt_RPGnum_')
+     d                                     like(CURLcode)
+     d  curl                           *   value                                CURLM *
+     d  option                             value like(CURLMoption)
+     d  numarg                       20i 0 value
+      *
+     d curl_multi_setopt...
+     d                 pr                  like(CURLcode)
+     d                                     overload(curl_multi_setopt_RPGnum_:
+     d                                              curl_multi_setopt_object:
+     d                                              curl_multi_setopt_function)
+      *
+     d curl_share_setopt...
+     d                 pr                  like(CURLcode)
+     d                                     overload(curl_share_setopt_int:
+     d                                              curl_share_setopt_ptr:
+     d                                              curl_share_setopt_proc)
+      *
+     d curl_easy_getinfo...
+     d                 pr                  like(CURLcode)
+     d                                     overload(curl_easy_getinfo_long:
+     d                                              curl_easy_getinfo_off_t:
+     d                                              curl_easy_getinfo_double:
+     d                                              curl_easy_getinfo_ptr)
+      /endif
       *
       /endif