TTTT_C(5)
π¦ Tt/tt_c.h β ToolTalk definitions π¦
okay so bestie, this is the Tt/tt_c.h page from the (file formats) manual β yes, the ToolTalk definitions one, and it is literally giving iconic header-file energy β¨
πΈ NAME πΈ
Tt/tt_c.h β ToolTalk definitions
β¨ SYNOPSIS β¨
#include &<Tt/tt_c.h>
π DESCRIPTION π
Bestie, the Tt/tt_c.h header includes typedefs for these callback functions:
typedef Tt_filter_action (*Tt_filter_function)(const char *nodeid,
void *context,
void *accumulator);
typedef Tt_callback_action (*Tt_message_callback)(Tt_message m,
Tt_pattern p);
To enable developers to write multithreaded applications, the header defines this:
typedef enum tt_feature {
_TT_FEATURE_MULTITHREADED = 1, // Thread-safety
_TT_FEATURE_LAST // Enum end marker
} Tt_feature;
highkey note: the TT_FEATURE_MULTITHREADED value will be part of the libtt binary interface. no cap.
These would be accessed by calling code with corresponding #define constants:
#define TT_FEATURE_MULTITHREADED _TT_FEATURE_MULTITHREADED
in order that that calling code can then use cpp directives to control their use of features:
#if defined(TT_FEATURE_MULTITHREADED)
....
#endif
The header defines the TT_VERSION constant with the value 10200, indicating the version of the ToolTalk API. slay.
The header defines the Tt_status enumeration data type, with the following members and specific values:
typedef enum tt_status {
TT_OK = 0,
TT_WRN_NOTFOUND = 1,
TT_WRN_STALE_OBJID = 2,
TT_WRN_STOPPED = 3,
TT_WRN_SAME_OBJID = 4,
TT_WRN_START_MESSAGE = 5,
TT_WRN_APPFIRST = 512,
TT_WRN_LAST = 1024,
TT_ERR_CLASS = 1025,
TT_ERR_DBAVAIL = 1026,
TT_ERR_DBEXIST = 1027,
TT_ERR_FILE = 1028,
TT_ERR_INVALID = 1029,
TT_ERR_MODE = 1031,
TT_ERR_ACCESS = 1032,
TT_ERR_NOMP = 1033,
TT_ERR_NOTHANDLER = 1034,
TT_ERR_NUM = 1035,
TT_ERR_OBJID = 1036,
TT_ERR_OP = 1037,
TT_ERR_OTYPE = 1038,
TT_ERR_ADDRESS = 1039,
TT_ERR_PATH = 1040,
TT_ERR_POINTER = 1041,
TT_ERR_PROCID = 1042,//The specified process identifier is out of date or invalid
TT_ERR_PROPLEN = 1043,
TT_ERR_PROPNAME = 1044,
TT_ERR_PTYPE = 1045,
TT_ERR_DISPOSITION = 1046,
TT_ERR_SCOPE = 1047,
TT_ERR_SESSION = 1048,
TT_ERR_VTYPE = 1049,
TT_ERR_NO_VALUE = 1050,
TT_ERR_INTERNAL = 1051,
TT_ERR_READONLY = 1052,
TT_ERR_NO_MATCH = 1053,
TT_ERR_UNIMP = 1054,
TT_ERR_OVERFLOW = 1055,
TT_ERR_PTYPE_START = 1056,
TT_ERR_CATEGORY = 1057,
TT_ERR_DBUPDATE = 1058,
TT_ERR_DBFULL = 1059,
TT_ERR_DBCONSIST = 1060,
TT_ERR_STATE = 1061,
TT_ERR_NOMEM = 1062,
TT_ERR_SLOTNAME = 1063,
TT_ERR_XDR = 1064,
TT_ERR_NETFILE = 1065,
TT_DESKTOP_ = 1100,
TT_DESKTOP_EPERM = 1101,
TT_DESKTOP_ENOENT = 1102,
TT_DESKTOP_EINTR = 1104,
TT_DESKTOP_EIO = 1105,
TT_DESKTOP_EAGAIN = 1111,
TT_DESKTOP_ENOMEM = 1112,
TT_DESKTOP_EACCES = 1113,
TT_DESKTOP_EFAULT = 1114,
TT_DESKTOP_EEXIST = 1117,
TT_DESKTOP_ENODEV = 1119,
TT_DESKTOP_ENOTDIR = 1120,
TT_DESKTOP_EISDIR = 1121,
TT_DESKTOP_EINVAL = 1122,
TT_DESKTOP_ENFILE = 1123,
TT_DESKTOP_EMFILE = 1124,
TT_DESKTOP_ETXTBSY = 1126,
TT_DESKTOP_EFBIG = 1127,
TT_DESKTOP_ENOSPC = 1128,
TT_DESKTOP_EROFS = 1130,
TT_DESKTOP_EMLINK = 1131,
TT_DESKTOP_EPIPE = 1132,
TT_DESKTOP_ENOMSG = 1135,
TT_DESKTOP_EDEADLK = 1145,
TT_DESKTOP_ECANCELED = 1147,
TT_DESKTOP_ENOTSUP = 1148,
TT_DESKTOP_ENODATA = 1161,
TT_DESKTOP_EPROTO = 1171,
TT_DESKTOP_ENOTEMPTY = 1193,
TT_DESKTOP_ETIMEDOUT = 1245,
TT_DESKTOP_EALREADY = 1249,
TT_DESKTOP_UNMODIFIED = 1299,
TT_MEDIA_ERR_SIZE = 1300,
TT_MEDIA_ERR_FORMAT = 1301,
TT_ERR_APPFIRST = 1536,
TT_ERR_LAST = 2047,
TT_STATUS_LAST = 2048
} Tt_status;
Specific values are required because they can be communicated between ToolTalk clients on different platforms, usually via tt_message_status_set(3) and tt_message_status(3). literally important, bestie.
The header defines the following enumeration data types, with at least the following members:
Tt_filter_actionβTT_FILTER_CONTINUE,TT_FILTER_LAST,TT_FILTER_STOPTt_callback_actionβTT_CALLBACK_CONTINUE,TT_CALLBACK_LAST,TT_CALLBACK_PROCESSEDTt_modeβTT_IN,TT_INOUT,TT_MODE_LAST,TT_MODE_UNDEFINED,TT_OUTTt_scopeβTT_BOTH,TT_FILE,TT_FILE_IN_SESSION,TT_SCOPE_NONE,TT_SESSIONTt_classβTT_CLASS_LAST,TT_CLASS_UNDEFINED,TT_NOTICE,TT_REQUESTTt_categoryβTT_CATEGORY_LAST,TT_CATEGORY_UNDEFINED,TT_HANDLE,TT_OBSERVETt_addressβTT_ADDRESS_LAST,TT_HANDLER,TT_OBJECT,TT_OTYPE,TT_PROCEDURETt_dispositionβTT_DISCARD,TT_QUEUE,TT_STARTTt_stateβTT_CREATED,TT_FAILED,TT_HANDLED,TT_QUEUED,TT_REJECTED,TT_SENT,TT_STARTED,TT_STATE_LAST
The header defines the following as opaque data types: Tt_message, Tt_pattern.
The header declares the following as functions:
char *tt_X_session(const char *xdisplaystring);
Tt_status tt_bcontext_join(const char *slotname,
const unsigned char *value,
int length);
Tt_status tt_bcontext_quit(const char *slotname,
const unsigned char *value,
int length);
Tt_status tt_close(void);
Tt_status tt_context_join(const char *slotname,
const char *value);
Tt_status tt_context_quit(const char *slotname,
const char *value);
char *tt_default_file(void);
Tt_status tt_default_file_set(const char *docid);
char *tt_default_procid(void);
Tt_status tt_default_procid_set(const char *procid);
char *tt_default_ptype(void);
Tt_status tt_default_ptype_set(const char *ptid);
char *tt_default_session(void);
Tt_status tt_default_session_set(const char *sessid);
int tt_error_int(Tt_status ttrc);
void *tt_error_pointer(Tt_status ttrc);
int tt_fd(void);
Tt_status tt_file_copy(const char *oldfilepath,
const char *newfilepath);
Tt_status tt_file_destroy(const char *filepath);
Tt_status tt_file_join(const char *filepath);
Tt_status tt_file_move(const char *oldfilepath,
const char *newfilepath);
char *tt_file_netfile(const char *filename);
Tt_status tt_file_objects_query(const char *filepath,
Tt_filter_function filter,
void *context,
void *accumulator);
Tt_status tt_file_quit(const char *filepath);
void tt_free(caddr_t p);
char *tt_host_file_netfile(const char *host,
const char *filename);
char *tt_host_netfile_file(const char *host,
const char *netfilename);
Tt_status tt_icontext_join(const char *slotname, int value);
Tt_status tt_icontext_quit(const char *slotname, int value);
char *tt_initial_session(void);
Tt_status tt_int_error(int return_val);
int tt_is_err(Tt_status s);
caddr_t tt_malloc(size_t s);
int tt_mark(void);
Tt_status tt_message_accept(Tt_message m);
Tt_address tt_message_address(Tt_message m);
Tt_status tt_message_address_set(Tt_message m, Tt_address a);
Tt_status tt_message_arg_add(Tt_message m,
Tt_mode n,
const char *vtype,
const char *value);
Tt_status tt_message_arg_bval(Tt_message m,
int n,
unsigned char **value,
int *len);
Tt_status tt_message_arg_bval_set(Tt_message m,
int n,
const unsigned char *value,
int len);
Tt_status tt_message_arg_ival(Tt_message m,
int n,
int *value);
Tt_status tt_message_arg_ival_set(Tt_message m,
int n,
int value);
Tt_mode tt_message_arg_mode(Tt_message m,
int n);
char *tt_message_arg_type(Tt_message m,
int n);
char *tt_message_arg_val(Tt_message m,
int n);
Tt_status tt_message_arg_val_set(Tt_message m,
int n,
const char *value);
Tt_status tt_message_arg_xval(Tt_message m,
int n,
xdrproc_t xdr_proc,
void **value);
Tt_status tt_message_arg_xval_set(Tt_message m,
int n,
xdrproc_t xdr_proc,
void *value);
int tt_message_args_count(Tt_message m);
Tt_status tt_message_barg_add(Tt_message m,
Tt_mode n,
const char *vtype,
const unsigned char *value,
int len);
Tt_status tt_message_bcontext_set(Tt_message m,
const char *slotname,
const unsigned char *value,
int length);
Tt_status tt_message_callback_add(Tt_message m,
Tt_message_callback f);
Tt_class tt_message_class(Tt_message m);
Tt_status tt_message_class_set(Tt_message m,
Tt_class c);
Tt_status tt_message_context_bval(Tt_message m,
const char *slotname,
unsigned char **value,
int *len);
Tt_status tt_message_context_ival(Tt_message m,
const char *slotname,
int *value);
Tt_status tt_message_context_set(Tt_message m,
const char *slotname,
const char *value);
char *tt_message_context_slotname(Tt_message m,
int n);
char *tt_message_context_val(Tt_message m,
const char *slotname);
Tt_status tt_message_context_xval(Tt_message m,
const char *slotname,
xdrproc_t xdr_proc,
void **value);
int tt_message_contexts_count(Tt_message m);
Tt_message tt_message_create(void);
Tt_message tt_message_create_super(Tt_message m);
...and the list keeps going, bestie, because of course it does π β so here's the rest of the prototypes, chunked so your eyes don't fall out.
π«Ά the message ones (grab it, tweak it, yeet it)
Everything that takes a Tt_message m and either reads a field off it or writes a field back. Getter, setter, getter, setter β it's giving matching tracksuit energy.
Tt_status tt_message_destroy(Tt_message m);
Tt_disposition tt_message_disposition(Tt_message m);
Tt_status tt_message_disposition_set(Tt_message m,
Tt_disposition r);
Tt_status tt_message_fail(Tt_message m);
char *tt_message_file(Tt_message m);
Tt_status tt_message_file_set(Tt_message m,
const char *file);
gid_t tt_message_gid(Tt_message m);
char *tt_message_handler(Tt_message m);
char *tt_message_handler_ptype(Tt_message m);
Tt_status tt_message_handler_ptype_set(Tt_message m,
const char *ptid);
Tt_status tt_message_handler_set(Tt_message m,
const char *procid);
Tt_status tt_message_iarg_add(Tt_message m,
Tt_mode n,
const char *vtype,
int value);
Tt_status tt_message_icontext_set(Tt_message m,
const char *slotname,
int value);
char *tt_message_id(Tt_message m);
char *tt_message_object(Tt_message m);
Tt_status tt_message_object_set(Tt_message m,
const char *objid);
char *tt_message_op(Tt_message m);
Tt_status tt_message_op_set(Tt_message m,
const char *opname);
int tt_message_opnum(Tt_message m);
char *tt_message_otype(Tt_message m);
Tt_status tt_message_otype_set(Tt_message m,
const char *otype);
Tt_pattern tt_message_pattern(Tt_message m);
char *tt_message_print(Tt_message *m);
Tt_message tt_message_receive(void);
Tt_status tt_message_reject(Tt_message m);
Tt_status tt_message_reply(Tt_message m);
Tt_scope tt_message_scope(Tt_message m);
Tt_status tt_message_scope_set(Tt_message m,
Tt_scope s);
Tt_status tt_message_send(Tt_message m);
Tt_status tt_message_send_on_exit(Tt_message m);
char *tt_message_sender(Tt_message m);
char *tt_message_sender_ptype(Tt_message m);
Tt_status tt_message_sender_ptype_set(Tt_message m,
const char *ptid);
char *tt_message_session(Tt_message m);
Tt_status tt_message_session_set(Tt_message m,
const char *sessid);
Tt_state tt_message_state(Tt_message m);
int tt_message_status(Tt_message m);
Tt_status tt_message_status_set(Tt_message m,
int status);
char *tt_message_status_string(Tt_message m);
Tt_status tt_message_status_string_set(Tt_message m,
const char *status_str);
uid_t tt_message_uid(Tt_message m);
void *tt_message_user(Tt_message m,
int key);
Tt_status tt_message_user_set(Tt_message m,
int key,
void *v);
Tt_status tt_message_xarg_add(Tt_message m,
Tt_mode n,
const char *vtype,
xdrproc_t xdr_proc,
void *value);
Tt_status tt_message_xcontext_join(const char *slotname,
xdrproc_t xdr_proc,
void *value);
Tt_status tt_message_xcontext_set(Tt_message m,
const char *slotname,
xdrproc_t xdr_proc,
void *value);
Quick vibe map so you're not lost π§:
tt_message_destroyis the goodbye kiss β status comes back.tt_message_disposition/..._setread and write the disposition, typed asTt_disposition.tt_message_failβ exactly what it sounds like.tt_message_file/..._setdeal inchar *on the way out andconst char *fileon the way in.tt_message_gidhands you agid_t, because group IDs have main character energy too.tt_message_handler,tt_message_handler_ptypereturn strings; their_settwins take aconst char *procidand aconst char *ptid.tt_message_iarg_addandtt_message_icontext_setare theint-flavoured arg/context adders.tt_message_printis special β it takes aTt_message *(a pointer, notice her π ) and gives you achar *.tt_message_receiveis the only one here takingvoid. She's the door, not the doorknob.tt_message_user/tt_message_user_setare yourint keyβvoid *hooks.tt_message_xarg_addandtt_message_xcontext_setare the XDR-flavoured versions βxdrproc_t xdr_procandvoid *value, andtt_message_xcontext_joindoesn't even need a message.
π¦ the bitties with their own names
These ones don't hang off a message at all β netfiles, objids, notices, requests, and the whole otype signature family.
char *tt_netfile_file(const char *netfilename);
int tt_objid_equal(const char *objid1,
const char *objid2);
char *tt_objid_objkey(const char *objid);
Tt_message tt_onotice_create(const char *objid,
const char *op);
char *tt_open(void);
Tt_message tt_orequest_create(const char *objid,
const char *op);
char *tt_otype_base(const char *otype);
char *tt_otype_derived(const char *otype,
int i);
int tt_otype_deriveds_count(const char *otype);
Tt_mode tt_otype_hsig_arg_mode(const char *otype,
int sig,
int arg);
char *tt_otype_hsig_arg_type(const char *otype,
int sig,
int arg);
int tt_otype_hsig_args_count(const char *otype,
int sig);
int tt_otype_hsig_count(const char *otype);
char *tt_otype_hsig_op(const char *otype,
int sig);
int tt_otype_is_derived(const char *derivedotype,
const char *baseotype);
Tt_status tt_otype_opnum_callback_add(const char *otid,
int opnum,
Tt_message_callback f);
Tt_mode tt_otype_osig_arg_mode(const char *otype,
int sig,
int arg);
char *tt_otype_osig_arg_type(const char *otype,
int sig,
int arg);
int tt_otype_osig_args_count(const char *otype,
int sig);
int tt_otype_osig_count(const char*otype);
char *tt_otype_osig_op(const char *otype,
int sig);
Obsessed with the little details here β¨:
tt_objid_equaltakes two objids and gives you anint(not aTt_status! she's different).- The
hsigfamily (tt_otype_hsig_arg_mode,tt_otype_hsig_arg_type,tt_otype_hsig_args_count,tt_otype_hsig_count,tt_otype_hsig_op) and theosigfamily (tt_otype_osig_arg_mode,tt_otype_osig_arg_type,tt_otype_osig_args_count,tt_otype_osig_count,tt_otype_osig_op) both walkotype,sig,argcoordinates. Note thattt_otype_osig_countis writtenconst char*otypewith no space β not a typo, that's literally the header, don't come for me π. tt_otype_opnum_callback_addtakes anotid, anopnum, and aTt_message_callback f.
π patterns (make a matcher, then register it)
The whole tt_pattern_* set β one builder per field, plus create/destroy/register/unregister and the user-hook pair.
Tt_status tt_pattern_address_add(Tt_pattern p,
Tt_address d);
Tt_status tt_pattern_arg_add(Tt_pattern p,
Tt_mode n,
const char *vtype,
const char *value);
Tt_status tt_pattern_barg_add(Tt_pattern m,
Tt_mode n,
const char *vtype,
const unsigned char *value,
int len);
Tt_status tt_pattern_bcontext_add(Tt_pattern p,
const char *slotname,
const unsigned char *value,
int length);
Tt_status tt_pattern_callback_add(Tt_pattern m,
Tt_message_callback f);
Tt_category tt_pattern_category(Tt_pattern p);
Tt_status tt_pattern_category_set(Tt_pattern p,
Tt_category c);
Tt_status tt_pattern_class_add(Tt_pattern p,
Tt_class c);
Tt_status tt_pattern_context_add(Tt_pattern p,
const char *slotname,
const char *value);
Tt_pattern tt_pattern_create(void);
Tt_status tt_pattern_destroy(Tt_pattern p);
Tt_status tt_pattern_disposition_add(Tt_pattern p,
Tt_disposition r);
Tt_status tt_pattern_file_add(Tt_pattern p,
const char *file);
Tt_status tt_pattern_iarg_add(Tt_pattern m,
Tt_mode n,
const char *vtype,
int value);
Tt_status tt_pattern_icontext_add(Tt_pattern p,
const char *slotname,
int value);
Tt_status tt_pattern_object_add(Tt_pattern p,
const char *objid);
Tt_status tt_pattern_op_add(Tt_pattern p,
const char *opname);
Tt_status tt_pattern_opnum_add(Tt_pattern p,
int opnum);
Tt_status tt_pattern_otype_add(Tt_pattern p,
const char *otype);
char *tt_pattern_print(Tt_pattern *p);
Tt_status tt_pattern_register(Tt_pattern p);
Tt_status tt_pattern_scope_add(Tt_pattern p,
Tt_scope s);
Tt_status tt_pattern_sender_add(Tt_pattern p,
const char *procid);
Tt_status tt_pattern_sender_ptype_add(Tt_pattern p,
const char *ptid);
Tt_status tt_pattern_session_add(Tt_pattern p,
const char *sessid);
Tt_status tt_pattern_state_add(Tt_pattern p,
Tt_state s);
Tt_status tt_pattern_unregister(Tt_pattern p);
void *tt_pattern_user(Tt_pattern p,
int key);
Tt_status tt_pattern_user_set(Tt_pattern p,
int key,
void *v);
Tt_status tt_pattern_xarg_add(Tt_pattern m,
Tt_mode n,
const char *vtype,
xdrproc_t xdr_proc,
void *value);
Tt_status tt_pattern_xcontext_add(Tt_pattern p,
const char *slotname,
xdrproc_t xdr_proc,
void *value);
Not me clocking the naming chaos π β most of these take Tt_pattern p, but tt_pattern_barg_add, tt_pattern_callback_add, tt_pattern_iarg_add and tt_pattern_xarg_add spell their first param Tt_pattern m. Same type, different letter. Copy the signature, don't copy my confusion.
Also: tt_pattern_print takes a Tt_pattern * and returns char *, while tt_pattern_category returns a Tt_category (plain, no Tt_status), and tt_pattern_user returns void *.
π§ pnotice, prequest, pointer checks, ptypes, and tt_release
Tt_message tt_pnotice_create(Tt_scope scope,
const char *op);
Tt_status tt_pointer_error(void *pointer);
Tt_message tt_prequest_create(Tt_scope scope,
const char *op);
Tt_status tt_ptr_error(pointer);
Tt_status tt_ptype_declare(const char *ptid);
Tt_status tt_ptype_exists(const char *ptid);
Tt_status tt_ptype_opnum_callback_add(const char *ptid,
int opnum,
Tt_message_callback f);
Tt_status tt_ptype_undeclare(const char *ptid);
void tt_release(int mark);
bestie. look attt_ptr_error(pointer). No type. Justpointer. That's the header, that's what's written, and honestly? iconic of whoever shipped it π
Also note tt_release returns void and takes an int mark β she gives nothing back, she just takes.
πΈ session properties (name/value energy)
Bytes version first, then the string version, plus join/quit/load.
Tt_status tt_session_bprop(const char *sessid,
const char *propname,
int i,
unsigned char **value,
int *length);
Tt_status tt_session_bprop_add(const char *sessid,
const char *propname,
const unsigned char *value,
int length);
Tt_status tt_session_bprop_set(const char *sessid,
const char *propname,
const unsigned char *value,
int length);
Tt_status tt_session_join(const char *sessid);
char *tt_session_prop(const char *sessid,
const char *propname,
int i);
Tt_status tt_session_prop_add(const char *sessid,
const char *propname,
const char *value);
int tt_session_prop_count(const char *sessid,
const char *propname);
Tt_status tt_session_prop_set(const char *sessid,
const char *propname,
const char *value);
char *tt_session_propname(const char *sessid,
int n);
int tt_session_propnames_count(const char *sessid);
Tt_status tt_session_quit(const char *sessid);
Tt_status tt_session_types_load(const char *session,
const char *filename);
Note the bprop trio is the unsigned char * / int length one, and tt_session_bprop additionally hands back unsigned char **value and int *length. The plain prop ones are all const char *value / char * returns. And tt_session_types_load calls its first arg session, not sessid β yes, really π
π spec properties (objid instead of sessid, same energy)
Tt_status tt_spec_bprop(const char *objid,
const char *propname,
int i,
unsigned char **value,
int *length);
Tt_status tt_spec_bprop_add(const char *objid,
const char *propname,
const unsigned char *value,
int length);
Tt_status tt_spec_bprop_set(const char *objid,
const char *propname,
const unsigned char *value,
int length);
char *tt_spec_create(const char *filepath);
Tt_status tt_spec_destroy(const char *objid);
char *tt_spec_file(const char *objid);
char *tt_spec_move(const char *objid,
const char *newfilepath);
char *tt_spec_prop(const char *objid,
const char *propname,
int i);
Tt_status tt_spec_prop_add(const char *objid,
const char *propname,
const char *value);
int tt_spec_prop_count(const char *objid,
const char *propname);
Tt_status tt_spec_prop_set(const char *objid,
const char *propname,
const char *value);
char *tt_spec_propname(const char *objid,
int n);
int tt_spec_propnames_count(const char *objid);
char *tt_spec_type(const char *objid);
Tt_status tt_spec_type_set(const char *objid,
const char *otid);
Tt_status tt_spec_write(const char *objid);
tt_spec_move takes two strings β objid and newfilepath β and tt_spec_create starts you off with a filepath. Cute little family π
β the last three (say hi)
char *tt_status_message(Tt_status ttrc);
int tt_trace_control(int onoff);
Tt_status tt_xcontext_quit(const char *slotname,
xdrproc_t xdr_proc,
void *value);
tt_status_message turns a Tt_status ttrc into a char *. tt_trace_control flips tracing with an int onoff and gives you an int back. tt_xcontext_quit is the no-message cousin of the xcontext calls, taking slotname, xdr_proc and value.
And that's the whole prototype parade, bestie π everything from tt_message_destroy down to tt_xcontext_quit, nothing skipped, nothing renamed. This page lives in the Tt/tt_c.h corner of the manual and is filed under (file formats) β no date on this footer, so don't ask me for one, I'm not making it up ππ
Go forth and call your functions, queen ππ«Ά
π¦ where this page comes from
- nixos 26.05: cde 2.5.3
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms