Fun 0.41.5
The programming language that makes you have fun!
Loading...
Searching...
No Matches
get.c
Go to the documentation of this file.
1/*
2 * This file is part of the Fun programming language.
3 * https://fun-lang.xyz/
4 *
5 * Copyright 2025 Johannes Findeisen <you@hanez.org>
6 * Licensed under the terms of the Apache-2.0 license.
7 * https://opensource.org/license/apache-2-0
8 */
9
10/**
11 * @file get.c
12 * @brief Fun VM opcode snippet: HTTP GET via libcurl (OP_CURL_GET).
13 *
14 * This snippet is included by vm.c and implements the OP_CURL_GET
15 * instruction. When FUN_WITH_CURL is enabled, it performs an HTTP GET
16 * request for the provided URL and pushes the response body as a string.
17 * If libcurl support is not built in, or an error occurs, an empty string
18 * is pushed instead.
19 *
20 * Stack behavior:
21 * - Pops: url:string (any value is converted via value_to_string_alloc)
22 * - Pushes: body:string ("" on error or when CURL is disabled)
23 *
24 * Converts the top stack value to a URL string, issues a GET request
25 * using libcurl, and pushes the response body as a string. When
26 * compiled without FUN_WITH_CURL, the opcode becomes a no-op that
27 * consumes one value and pushes an empty string.
28 *
29 * Error handling:
30 * - If URL conversion fails or CURL initialization/performance fails,
31 * the opcode pushes an empty string.
32 * - Follows HTTP redirects (CURLOPT_FOLLOWLOCATION = 1L).
33 *
34 * Notes:
35 * - Uses FunCurlBuf and fun_curl_write_cb from the curl extension helpers.
36 * - Memory allocated for temporary strings and buffers is freed before exit.
37 */
38
40#ifdef FUN_WITH_CURL
41 Value vurl = pop_value(vm);
44 if (!url) {
45 push_value(vm, make_string(""));
46 break;
47 }
48 FunCurlBuf buf = {NULL, 0};
49 CURL *h = curl_easy_init();
50 if (!h) {
51 free(url);
52 push_value(vm, make_string(""));
53 break;
54 }
55 curl_easy_setopt(h, CURLOPT_URL, url);
56 curl_easy_setopt(h, CURLOPT_FOLLOWLOCATION, 1L);
57 curl_easy_setopt(h, CURLOPT_WRITEFUNCTION, fun_curl_write_cb);
58 curl_easy_setopt(h, CURLOPT_WRITEDATA, &buf);
59 CURLcode rc = curl_easy_perform(h);
62 if (rc != CURLE_OK) {
63 if (buf.d) free(buf.d);
64 push_value(vm, make_string(""));
65 break;
66 }
67 Value s = make_string(buf.d ? buf.d : "");
68 if (buf.d) free(buf.d);
70#else
71 Value v = pop_value(vm);
73 push_value(vm, make_string(""));
74#endif
75 break;
76}
@ OP_CURL_GET
Definition bytecode.h:173
Value v
Definition cast.c:22
static size_t fun_curl_write_cb(void *ptr, size_t sz, size_t nm, void *ud)
libcurl write callback that appends data to a FunCurlBuf.
Definition curl.c:45
CURLcode rc
Definition download.c:71
CURL * h
Definition download.c:59
Value vurl
Definition download.c:41
char * url
Definition download.c:42
curl_easy_cleanup(h)
free_value(vurl)
FunCurlBuf buf
Definition get.c:48
curl_easy_setopt(h, CURLOPT_URL, url)
push_value(vm, s)
free(url)
uint32_t s
Definition rol.c:31
Simple growable buffer for libcurl write callbacks.
Definition curl.c:28
Tagged union representing a Fun value.
Definition value.h:68
Value make_string(const char *s)
Construct a string Value by duplicating the given C string.
Definition value.c:95
char * value_to_string_alloc(const Value *v)
Allocate a printable C string for a Value.
Definition value.c:641
static Value pop_value(VM *vm)
Pop a Value from the VM operand stack.
Definition vm.c:580