diff options
| author | 2023-03-24 10:12:51 -0400 | |
|---|---|---|
| committer | 2023-03-24 10:12:51 -0400 | |
| commit | 966bdd6e94555f0889e7661f4dcc85ee0a5d38bc (patch) | |
| tree | 001f91f9d51650c9537db975313f486563a2fb00 /src | |
| parent | native: fix two potential runoffs (diff) | |
native: ok this is kind of big, see rest of message
splitting this like usual was too much effort sorry
* implement mime-headers
* move util stuff out of jurl.c
* reorganize header a bit (will do more of this soon)
* make cleanup universal
* wrap slist generation
Diffstat (limited to 'src')
| -rw-r--r-- | src/cleanup.c | 24 | ||||
| -rw-r--r-- | src/jurl.c | 79 | ||||
| -rw-r--r-- | src/jurl.h | 30 | ||||
| -rw-r--r-- | src/mime.c | 18 | ||||
| -rw-r--r-- | src/setopt.c | 2 | ||||
| -rw-r--r-- | src/util.c | 72 |
6 files changed, 131 insertions, 94 deletions
diff --git a/src/cleanup.c b/src/cleanup.c new file mode 100644 index 0000000..5e387a3 --- /dev/null +++ b/src/cleanup.c @@ -0,0 +1,24 @@ +#include "jurl.h" + +void jurl_do_cleanup(struct jurl_cleanup **src) { + while (src) { + struct jurl_cleanup *cur = *src; + switch (cur->type) { + case JURL_CLEANUP_TYPE_SLIST: + curl_slist_free_all(cur->slist); + break; + default: + janet_panic("unknown type of cleanup data in do_cleanup"); + } + *src = cur->next; + free(cur); + } +} + +struct jurl_cleanup *register_cleanup(struct jurl_cleanup **prev, enum jurl_cleanup_type type) { + struct jurl_cleanup *out = malloc(sizeof(struct jurl_cleanup)); + out->next = *prev; + *prev = out; + out->type = type; + return out; +} @@ -5,18 +5,7 @@ static int jurl_gc(void *p, size_t s) { (void) s; jurl_handle *jurl = (jurl_handle*)p; if (jurl->handle) curl_easy_cleanup(jurl->handle); - while (jurl->cleanup) { - struct jurl_cleanup *cur = jurl->cleanup; - switch (cur->type) { - case JURL_CLEANUP_TYPE_SLIST: - curl_slist_free_all(cur->slist); - break; - default: - janet_panic("unknown type of cleanup data in jurl_gc"); - } - jurl->cleanup = cur->next; - free(cur); - } + jurl_do_cleanup(&jurl->cleanup); return 0; } @@ -72,64 +61,6 @@ jurl_handle *janet_getjurl(Janet *argv, int32_t n) { return (jurl_handle*)janet_getabstract(argv, n, &jurl_type); } -// this function plays fast and loose and I hope the gc doesn't kill me for it -// anyway, it goes like so: -// (wrap-error :ok something) -> [:ok something] -// (wrap-error :err something) -> [:err "explanation of :err"] -JANET_CFUN(jurl_wrap_error) { - janet_fixarity(argc, 2); - CURLcode code; - if (janet_checktype(argv[0], JANET_NUMBER)) { - argv[0] = jurl_geterror(janet_getinteger(argv, 0)); - } - if (!janet_checktype(argv[0], JANET_KEYWORD)) { - janet_panicf("jurl_wrap_error: expected number or keyword, got %T", janet_type(argv[0])); - } - if (!janet_keyeq(argv[0], "ok")) { - // will this break one day? - // find out next time! - argv[1] = jurl_strerror(1, argv); - } - return janet_wrap_tuple(janet_tuple_n(argv, 2)); -} - -JANET_CFUN(jurl_escape) { - janet_fixarity(argc, 1); - JanetByteView b = janet_getbytes(argv, 0); - CURL* curl; -#if !CURL_AT_LEAST_VERSION(7,82,0) - curl = curl_easy_init(); -#endif - - char *s = curl_easy_escape(curl, (const char*)b.bytes, b.len); - Janet out = janet_cstringv(s); - - curl_free(s); -#if !CURL_AT_LEAST_VERSION(7,82,0) - curl_easy_cleanup(curl); -#endif - return out; -} - -JANET_CFUN(jurl_unescape) { - janet_fixarity(argc, 1); - JanetByteView b = janet_getbytes(argv, 0); - CURL *curl; -#if !CURL_AT_LEAST_VERSION(7,82,0) - curl = curl_easy_init(); -#endif - - int len; - char *s = curl_easy_unescape(curl, (const char*)b.bytes, b.len, &len); - Janet out = janet_stringv((const uint8_t*)s, len); - - curl_free(s); -#if !CURL_AT_LEAST_VERSION(7,82,0) - curl_easy_cleanup(curl); -#endif - return out; -} - JANET_CFUN(jurl_new) { janet_fixarity(argc, 0); jurl_handle *jurl = (jurl_handle*)janet_abstract(&jurl_type, sizeof(jurl_handle)); @@ -138,14 +69,6 @@ JANET_CFUN(jurl_new) { return janet_wrap_abstract(jurl); } -struct jurl_cleanup *register_cleanup(jurl_handle *jurl, enum jurl_cleanup_type type) { - struct jurl_cleanup *out = malloc(sizeof(struct jurl_cleanup)); - out->next = jurl->cleanup; - jurl->cleanup = out; - out->type = type; - return out; -} - JANET_CFUN(jurl_reset) { janet_fixarity(argc, 1); jurl_handle *jurl = janet_getjurl(argv, 0); @@ -2,7 +2,7 @@ #include <curl/curl.h> #include <janet.h> -// jurl globals +// cleanup.c enum jurl_cleanup_type { JURL_CLEANUP_TYPE_SLIST, }; @@ -14,40 +14,40 @@ struct jurl_cleanup { }; }; +struct jurl_cleanup *register_cleanup(struct jurl_cleanup **prev, enum jurl_cleanup_type type); +void jurl_do_cleanup(struct jurl_cleanup **src); + +// jurl.c struct jurl_handle { CURL* handle; struct jurl_cleanup* cleanup; }; typedef struct jurl_handle jurl_handle; -// jurl.c -struct jurl_cleanup *register_cleanup(jurl_handle *jurl, enum jurl_cleanup_type type); -JANET_CFUN(jurl_escape); -JANET_CFUN(jurl_unescape); JANET_CFUN(jurl_new); JANET_CFUN(jurl_reset); JANET_CFUN(jurl_dup); JANET_CFUN(jurl_perform); -JANET_CFUN(jurl_wrap_error); jurl_handle *janet_getjurl(Janet *argv, int32_t n); -// jurl_callbacks.c +// callbacks.c CURLcode jurl_setcallback(jurl_handle *jurl, CURLoption opt, JanetFunction *fun); -// jurl_enums.c +// enums.c CURLcode jurl_setenum(jurl_handle *jurl, CURLoption opt, Janet val); -// jurl_errors.c +// errors.c Janet jurl_geterror(CURLcode code); JANET_CFUN(jurl_strerror); -// jurl_getinfo.c +// getinfo.c JANET_CFUN(jurl_getinfo); -// jurl_mime.c +// mime.c struct jurl_mime { CURL *curl; curl_mime *handle; + struct jurl_cleanup* cleanup; int clean; }; typedef struct jurl_mime jurl_mime; @@ -64,5 +64,11 @@ JANET_CFUN(jurl_mime_encoder); JANET_CFUN(jurl_mime_subparts); jurl_mime *janet_getjurlmime(Janet *argv, int32_t n); -// jurl_setopt.c +// setopt.c JANET_CFUN(jurl_setopt); + +// util.c +int janet_getslist(struct curl_slist **slist, Janet *argv, int32_t n); +JANET_CFUN(jurl_escape); +JANET_CFUN(jurl_unescape); +JANET_CFUN(jurl_wrap_error); @@ -6,6 +6,7 @@ static int jurl_mime_gc(void *p, size_t s) { jurl_mime *mime = (jurl_mime*)p; if (mime->clean) curl_mime_free(mime->handle); curl_easy_cleanup(mime->curl); + jurl_do_cleanup(&mime->cleanup); return 0; } @@ -182,10 +183,21 @@ JANET_CFUN(jurl_mime_type) { return jurl_geterror(ret); } -// TODO: really? I have to do cleanup *again*? ;-; +// due to how the cleanup works, I either have to convert mimepart to an abstract +// or also pass through the mime +// I opt for option 2 for now +// note that the part MUST belong to the mime JANET_CFUN(jurl_mime_headers) { - janet_panic("not implemented"); - return janet_wrap_nil(); // unreachable + janet_fixarity(argc, 3); + jurl_mime *mime = janet_getjurlmime(argv, 0); + curl_mimepart *part = (curl_mimepart*)janet_getpointer(argv, 1); + struct jurl_cleanup *clean = register_cleanup(&mime->cleanup, JURL_CLEANUP_TYPE_SLIST); + if (!janet_getslist(&clean->slist, argv, 2)) { + janet_panicf("failed to get slist in jurl_mime_headers, got %v", argv[2]); + } + return jurl_geterror( + curl_mime_headers(part, clean->slist, 0) + ); } JANET_CFUN(jurl_mime_encoder) { diff --git a/src/setopt.c b/src/setopt.c index e000731..cabb9a6 100644 --- a/src/setopt.c +++ b/src/setopt.c @@ -417,7 +417,7 @@ JANET_CFUN(jurl_setopt) { break; case JURL_PARAMTYPE_SLIST: { // we register the cleanup ahead of time, because... - struct jurl_cleanup *clean = register_cleanup(jurl, JURL_CLEANUP_TYPE_SLIST); + struct jurl_cleanup *clean = register_cleanup(&jurl->cleanup, JURL_CLEANUP_TYPE_SLIST); JanetView args = janet_getindexed(argv, 2); for (int32_t i = 0; i < args.len; i++) { diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..a9a526b --- /dev/null +++ b/src/util.c @@ -0,0 +1,72 @@ +#include "jurl.h" + +int janet_getslist(struct curl_slist **slist, Janet *argv, int32_t n) { + JanetView args = janet_getindexed(argv, n); + for (int32_t i = 0; i< args.len; i++) { + const char *s = janet_getcstring(args.items, i); + struct curl_slist *newlist = curl_slist_append(*slist, s); + if (!newlist) { + return 0; + } + *slist = newlist; + } + return 1; +} + +JANET_CFUN(jurl_escape) { + janet_fixarity(argc, 1); + JanetByteView b = janet_getbytes(argv, 0); + CURL* curl; +#if !CURL_AT_LEAST_VERSION(7,82,0) + curl = curl_easy_init(); +#endif + + char *s = curl_easy_escape(curl, (const char*)b.bytes, b.len); + Janet out = janet_cstringv(s); + + curl_free(s); +#if !CURL_AT_LEAST_VERSION(7,82,0) + curl_easy_cleanup(curl); +#endif + return out; +} + +JANET_CFUN(jurl_unescape) { + janet_fixarity(argc, 1); + JanetByteView b = janet_getbytes(argv, 0); + CURL *curl; +#if !CURL_AT_LEAST_VERSION(7,82,0) + curl = curl_easy_init(); +#endif + + int len; + char *s = curl_easy_unescape(curl, (const char*)b.bytes, b.len, &len); + Janet out = janet_stringv((const uint8_t*)s, len); + + curl_free(s); +#if !CURL_AT_LEAST_VERSION(7,82,0) + curl_easy_cleanup(curl); +#endif + return out; +} + +// this function plays fast and loose and I hope the gc doesn't kill me for it +// anyway, it goes like so: +// (wrap-error :ok something) -> [:ok something] +// (wrap-error :err something) -> [:err "explanation of :err"] +JANET_CFUN(jurl_wrap_error) { + janet_fixarity(argc, 2); + CURLcode code; + if (janet_checktype(argv[0], JANET_NUMBER)) { + argv[0] = jurl_geterror(janet_getinteger(argv, 0)); + } + if (!janet_checktype(argv[0], JANET_KEYWORD)) { + janet_panicf("jurl_wrap_error: expected number or keyword, got %T", janet_type(argv[0])); + } + if (!janet_keyeq(argv[0], "ok")) { + // will this break one day? + // find out next time! + argv[1] = jurl_strerror(1, argv); + } + return janet_wrap_tuple(janet_tuple_n(argv, 2)); +} |
