Skip to content

Instantly share code, notes, and snippets.

@sigzegv
Last active September 14, 2023 14:16
Show Gist options
  • Save sigzegv/58bbfb21092b84ef1974bf3c2c1aefe0 to your computer and use it in GitHub Desktop.
Save sigzegv/58bbfb21092b84ef1974bf3c2c1aefe0 to your computer and use it in GitHub Desktop.
C snippets
char*
file_get_contents(const char* fname) {
FILE* f = fopen(fname, "r");
if (!f) {
printf("failed reading %s", fname);
return NULL;
}
fseek(f, 0, SEEK_END);
long sz = ftell(f);
fseek(f, 0, SEEK_SET);
char* content = malloc(sizeof(char) * sz + 1);
fread(content, sz, 1, f);
fclose(f);
content[sz] = '\0';
return content;
}
// https://stackoverflow.com/questions/7666509/hash-function-for-string
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define SEED 0x12345678
uint32_t DJB2_hash(const uint8_t *str)
{
uint32_t hash = 5381;
uint8_t c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
uint32_t FNV(const void* key, int len, uint32_t h)
{
// Source: https://github.com/aappleby/smhasher/blob/master/src/Hashes.cpp
h ^= 2166136261UL;
const uint8_t* data = (const uint8_t*)key;
for(int i = 0; i < len; i++)
{
h ^= data[i];
h *= 16777619;
}
return h;
}
uint32_t MurmurOAAT(const void * key, uint32_t h)
{
const uint8_t* str = (const uint8_t*)key;
// One-byte-at-a-time hash based on Murmur's mix
// Source: https://github.com/aappleby/smhasher/blob/master/src/Hashes.cpp
for (; *str; ++str) {
h ^= *str;
h *= 0x5bd1e995;
h ^= h >> 15;
}
return h;
}
uint32_t KR_v2_hash(const char *s)
{
// Source: https://stackoverflow.com/a/45641002/5407270
uint32_t hashval = 0;
for (hashval = 0; *s != '\0'; s++)
hashval = *s + 31*hashval;
return hashval;
}
uint32_t Jenkins_one_at_a_time_hash(const char *str, size_t len)
{
uint32_t hash, i;
for(hash = i = 0; i < len; ++i)
{
hash += str[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
uint32_t crc32b(const uint8_t *str) {
// Source: https://stackoverflow.com/a/21001712
unsigned int byte, crc, mask;
int i = 0, j;
crc = 0xFFFFFFFF;
while (str[i] != 0) {
byte = str[i];
crc = crc ^ byte;
for (j = 7; j >= 0; j--) {
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
i = i + 1;
}
return ~crc;
}
uint32_t _rotl32(uint32_t x, int32_t bits)
{
return x<<bits | x>>(32-bits); // C idiom: will be optimized to a single operation
}
uint32_t Coffin_hash(char const *input) {
// Source: https://stackoverflow.com/a/7666668/5407270
uint32_t result = 0x55555555;
while (*input) {
result ^= *input++;
result = _rotl32(result, 5);
}
return result;
}
uint32_t x17(const void * key, int len, uint32_t h)
{
// Source: https://github.com/aappleby/smhasher/blob/master/src/Hashes.cpp
const uint8_t * data = (const uint8_t*)key;
for (int i = 0; i < len; ++i)
{
h = 17 * h + (data[i] - ' ');
}
return h ^ (h >> 16);
}
int main() {
char *key = "samplekey";
uint32_t h = MurmurOAAT(key, SEED);
printf("%u\n", h);
return 0;
}
typedef struct hsearch_data htree_t;
htree_t*
htree_create(size_t sz) {
htree_t *h = malloc(sizeof(htree_t));
if (NULL == h) {
return NULL;
}
if (!hcreate_r(sz, h)) {
free(h);
return NULL;
}
return h;
}
int
htree_set(htree_t* h, char *key, void* data) {
ENTRY* i;
if (!hsearch_r((ENTRY){.key = key, .data = data}, ENTER, &i, h)) {
return 0;
}
return 1;
}
void*
htree_find(htree_t* h, char *key) {
ENTRY* res;
if (!hsearch_r((ENTRY){.key = key}, FIND, &res, h)) {
return NULL;
}
return res->data;
}
void
htree_delete(htree_t *h) {
hdestroy_r(h);
}
#include <ctype.h>
#include <string.h>
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
/**
* gets last char in string
*/
char *str_last(char *str) {
return str + strlen(str);
}
/**
* replace all occurences of 'o' by 'n' in str
*/
int str_replace_chr(char *str, char o, char n) {
char *p;
int count = 0;
while((p = strchr(str, o)) != NULL) {
*p = n;
count++;
}
return count;
}
/**
* Trim spaces in string str.
* The returned string has to be freed
*/
char *strtrim(const char *s) {
char* str = s;
// trim front
while(isspace((unsigned char)*str)) str++;
if(*str == 0) return str;
// trim trail
char *end = str + strlen(str) - 1;
while(end > str && isspace((unsigned char)*end)) end--;
end[1] = '\0'; // write new null terminator character
return str;
}
/**
* Extracts the string between st and end positions.
* st and end must be part of same string.
* Returned buffer must be freed
*/
char *str_extract(const char *st, const char *end) {
int len = end - st;
char *s = malloc(len + 1);
strncpy(s, st, len);
*(s + len) = '\0';
return s;
}
/**
* Searches for a substring in str, enclosed by st_tok and end_tok strings.
* Returned buffer must be freed
*/
char*
substr(const char *str, const char *st_tok, const char *end_tok) {
if (st_tok == end_tok) {
return NULL;
}
// reverse st_tok and end_tok if end_tok is before st_tok
if (end_tok < st_tok) {
char* tmp = st_tok;
st_tok = end_tok;
end_tok = tmp;
}
char *stpos = strstr(str, st_tok); // searches for first st_tok's occurence.
if (NULL == stpos) {
fprintf(stderr, "token %s not found", st_tok);
return NULL;
}
stpos += strlen(st_tok); // start searching after the end of 'st_tok''s matched occurence
char *endpos = strstr(stpos, end_tok); // searches for first end_tok's occurence
if (NULL == endpos) {
fprintf(stderr, "end token %s not found", end_tok);
return NULL;
}
return str_extract(stpos, endpos);
}
/**
* Splits a string against a separator.
* It keeps empty strings between twin separators.
*/
char **str_split(const char *str, const char sep) {
char *st = (char *)str;
char *last = NULL;
char **splits = NULL;
int count = 0;
while((last = strchr(st, sep)) != NULL) {
splits = realloc(splits, sizeof(char *) * (count+1));
char *m = str_extract(st, last);
*(splits + count) = m;
count++;
st = last + 1;
}
char *m = str_extract(st, str_last(st));
*(splits + count) = m;
return splits;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment