Skip to content

Instantly share code, notes, and snippets.

@stpettersens
Last active June 8, 2026 15:42
Show Gist options
  • Select an option

  • Save stpettersens/b91e55021314e61f3d440e7decb028da to your computer and use it in GitHub Desktop.

Select an option

Save stpettersens/b91e55021314e61f3d440e7decb028da to your computer and use it in GitHub Desktop.
Utility functions for C3
module util::id;
import libc;
alias Id = String;
fn Id generate_id(uint length) {
/* Valid IDs are a-z lowercase *length* char strings */
DString id = {};
while (id.len() < length) {
int r = (97 + (libc::rand() % 26));
id.appendf("%c", (char)r);
}
return id.str_view();
}
module util;
import libc;
import std::core;
import std::io;
import std::io::file;
import std::collections;
alias Bytes = char[];
extern fn char* _c_getenv(char* name) @cname("getenv");
fn String cstr_to_str(char* cstr) {
usz len = 0;
while (cstr[len] != 0) {
len++;
}
if (len == 0) return "";
return (String)cstr[0..len];
}
/* This is like env::tget_var("VARIABLE")!! but returns nothing gracefully */
fn String get_env_var(String variable) {
char* cstr = _c_getenv(variable);
if (!cstr) return "";
return cstr_to_str(cstr);
}
fn String str_upper(String s) {
DString uppercased = {};
foreach (ch : s) {
if (ch >= 'a' && ch <= 'z') {
ch -= 32;
}
uppercased.appendf("%c", ch);
}
return uppercased.str_view();
}
fn bool char_is_number(char ch) {
bool number = false;
if (ch >= '0' && ch <= '9') {
number = true;
}
return number;
}
fn String int_str(int n) {
DString str = {};
str.appendf("%d", n);
return str.str_view();
}
fn String uint_str(uint n) {
return int_str((int)n);
}
fn int str_int(String n) {
char* end;
return (int)libc::strtol(n, &end, 10);
}
fn uint str_uint(String n) {
return (uint)str_int(n);
}
fn uint hexadecimal_to_uint(String hex) {
char* end;
return (uint)libc::strtoul(hex, &end, 16);
}
/* Parses + integers, not negatives */
fn int parse_int_from_string(String str) {
DString n = {};
foreach (char ch : str) {
if (ch >= 48 && ch <= 57) {
n.appendf("%c", ch);
}
}
if (n.len() == 0) {
n.appendf("%c", '0');
}
return str_int(n.str_view());
}
fn bool int_bool(int n) {
if (n == 1) return true;
return false;
}
fn String bool_str(bool b) {
if (b) return "true";
return "false";
}
fn bool str_bool(String b) {
if (b == "true") return true;
return false;
}
fn Bytes str_to_bytes(String str) {
return (Bytes)str;
}
fn String join_str_list(List{String}* list, String join_chars) {
DString joined = {};
foreach (str : list) {
joined.appendf("%s%s", str, join_chars);
}
return joined.str_view();
}
fn String read_file_to_string(String filename) {
long size = file::get_size(filename)!!;
File f = file::open(filename, "rb")!!;
defer (void)f.close();
(void)f.seek(0, SeekOrigin.FROM_START);
char* buffer = mem::alloc_array(char, size);
long bytes_read = f.read(buffer[:size])!!;
return (String)buffer[:bytes_read];
}
fn void write_string_to_file(String filename, String data, bool newLine) {
File f = file::open(filename, "wb")!!;
defer (void)f.close();
f.write(data)!!;
if (newLine) f.write("\n")!!;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment