GOLF(2gg)

πŸ“¦ version 601.4.41, in ubuntu questing

✨ NAME ✨

Server-API β€” Golf documentation (API). That's the whole vibe, bestie. This is the manual page GOLF(2gg) from the Development section, and it's literally all about how to link your non-Golf code into your Golf app. πŸŽ€


πŸ’– DESCRIPTION πŸ’–

okay so first thing: Golf can be used in extended-mode, which is the mode where non-Golf code or libraries get linked right into your application. πŸ¦‹

That code can come from a library (peep the --llflag and --cflag options in gg), or it can just be straight-up C code you wrote yourself β€” like files with .c and .h extension hanging out next to your Golf application. To pull that off, you use the call-extended statement. πŸ’…

Any function with C linkage is fair game, as long as:

  • its parameters (whether by value or by reference) are only of type int64_t (that's the number type in Golf), bool (the bool type in Golf) or char * (the string type in Golf).
  • it must not return any value at all β€” like, it has to have a void return type. no exceptions. πŸ™ˆ

When you're allocating strings in extended code, you must use Golf memory management functions. These are based on the standard C library (things like malloc or free), but they are not compatible with them, because Golf manages that memory on top of the standard C library. so don't go mixing them, fr fr. 😭

The functions you can use are:

  • char *gg_strdup (char *s) β€” creates a copy of a null-terminated string s. A pointer to memory data is returned. ✨
  • char *gg_strdupl (char *s, gg_num from, gg_num l) β€” creates a copy of memory data pointed to by s, starting from byte from of length l. Note that from is indexed from 0. A pointer to memory data is returned. πŸ’«
  • void *gg_malloc(size_t size) β€” allocates memory of size size and returns a pointer to it.
  • void *gg_calloc(size_t nmemb, size_t size) β€” allocates nmemb blocks of memory (each of size size) and returns a pointer to it. Memory is initialized to all zero bytes. squeaky clean. 🧼
  • num gg_mem_get_id (void *ptr) β€” returns the Golf memory handle for memory ptr.
  • void *gg_realloc(gg_num r, size_t size) β€” reallocates memory identified with Golf memory handle r (see gg_mem_get_id()) to a new size of size and returns a pointer to it. Note that you can only reallocate the memory you created with gg_malloc() and gg_calloc() β€” do not attempt to reallocate Golf memory passed to your function. Golf in general never reallocates any existing memory in any statement. periodt. 🚫
  • void gg_mem_set_len (gg_num r, gg_num len) β€” sets the length of memory identified with Golf memory handle r to len bytes. Note that all Golf memory must have a null-byte at the end for consistency, regardless of whether such memory holds pure binary data or an actual null-delimited string. So for example, a string "abc" would have len set to 4 to include a null byte, and binary data "\xFF\x00\x01" (which consists of 3 bytes, the middle of which is a null byte) would have len also set to 4 and you would place an extra zero byte at the end of it even if it's not part of the actual useful data. Note that whatever memory length you set, it must be lesser or equal to the length of memory you have actually allocated. πŸ‘‘
  • num gg_mem_get_len (gg_num r) β€” returns the length of memory identified with Golf memory handle r. The length returned is 1 bytes less than the memory set by gg_mem_set_len(), so for example for string "abc" the return value would be 3, as it would be for "\xFF\x00\x01".

You can use gg_malloc(), gg_calloc() and gg_realloc() to create new Golf-compatible memory β€” and assuming you have set the last byte of any such memory to a null byte, the resulting memory will be properly sized for Golf usage. 🫢

If you have memory that's already provided from elsewhere, you can use gg_strdup() or gg_strdupl() to create a copy of it that's compatible with Golf. πŸ’œ

If Golf memory you created with these functions has extra unused bytes, you can use either gg_realloc() to reduce its footprint, or you can use gg_mem_set_len() to set its length. the way you have options?? obsessed. 🌸

Note: if you use C code included with a Golf project, you must include "golf.h" file in each of them. You do not need to manually include any other ".h" files (header files), as they will be automatically picked up. iconic behaviour, honestly. 🌈

πŸŽ€ EXAMPLES πŸŽ€

Place the following files in a separate directory for demonstration purposes.

In this example, "example.golf" will use C functions from "example.c", and "example.h" will have declarations of those functions. File "example.c" implements a factorial function, as well as a function that will store the factorial result in an output message that's allocated and passed back to your Golf code:

#include "golf.h"

void get_factorial(gg_num f, gg_num *res)
{
    *res = 1;
    gg_num i;
    for (i = 2; i <= f; i++) {
        *res *= i;
    }
}

#define MEMSIZE 200
void fact_msg (gg_num i, char **res)
{
    // golf rule: outgoing string must NOT free or realloc its incoming value
    // all else is allowed
    char *r = gg_malloc (MEMSIZE);
    gg_num f;
    get_factorial (i, &f);
    gg_num bw = snprintf(r, MEMSIZE, "Factorial value (message from C function) is %ld", f) + 1;
    // reduce memory footprint to match the memory used (including the null byte)
    // you can also use gg_mem_set_len() with bw as length for higher performance
    // (but also higher memory usage)
    *res = gg_realloc (gg_mem_get_id(r), bw);
}

File "example.h" declares the above functions:

void get_factorial(gg_num f, gg_num *res);
void fact_msg (gg_num i, char **res);

File "example.golf" will call the above functions and display the results:

extended-mode

begin-handler /example public

    set-number fact
    call-extended get_factorial (10, &fact)
    @Factorial is <<print-out fact>>

    set-string res
    call-extended fact_msg (10, &res)
    print-out res
    @
end-handler

Create application "example":

sudo mgrg -i -u $(whoami) example

Make the application:

gg -q

Run it:

gg -r --req="/example" --exec --silent-header

The output is, as expected:

Factorial is 3628800
Factorial value (message from C function) is 362880

πŸ¦‹ SEE ALSO πŸ¦‹

  • API
  • Client-API
  • Server-API
  • See all documentation

and that's the whole page, bestie πŸ’… this cutie was served up on $DATE at version $VERSION of the GOLF(2gg) manual β€” go forth and call-extended responsibly. mwah. πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from