Awesome
chadstr.h
Chad Strings - The Chad way to handle strings in C.
One str(...)
macro to handle them all.
Examples Usage:
int table = 13;
int id = 37;
str test1 = str("SELECT * FROM ", table, " where person_id ", id);
str test2 = str(test1); //copies test1 to test2
str test3 = str(test2, test1); // returns concat of test2 and test1
test2 = test1; // acceptable, but wrong since test2 now points to test1 not copies it.
str(*test1); // returns const char* to use in printf like functions
Ex: puts(str(*test1)); // prints test1;
"Why yes, i don't free(), OS cleans all memory for me, how did you know?"
<p> <img src="gc.gif" alt="animated" width="250" height="350" /> </p>free(test1); // will free memory for whole str.
"Whoa, whoa, wait bro. But how about freeing str->data field?"
While allocating memory for 'str' struct itself it also reserves space beneath it to store that string. str->data points to that location. So freeing str itself also frees memory located at str->data.
If your coompiler does support "__attribute__((cleanup()))"
("aahem gcc/clang"), strings can be auto free'd while defined this way:
autofree str test1 = str("apple");
...
// no free(test1); !!!
or
chadstr test2 = str("pineapple");
...
// no free(test2); !!!
Operations on Chad Strings:
Instead of writing shitload of different functions for some specific task, you can utilize already existing tools in your OS to do that for you.
<p> <img src="meme.png" /> </p>Examples Usage:
cmd CMD = (cmd){"echo"}
chadstr test1 = str("orange apple");
chadstr pipecmd = str(" | cut -z -d \" \" -f1 ");
chadstr result = str(CMD, test1, pipecmd); // "echo orange apple | cut -z -d " " -f1" as you would do in shell
/* chadstr result = str((cmd){"echo"}, test1, pipecmd); is also acceptable */
puts(str(*result));
File embedding has never been easier with ChadSTR:
cmd CAT = (cmd){"cat"};
chadstr file = str(CAT, "README.md"); // cat README.md
puts(str(*file));
ChadSTR also has utility function range()
to select range of string:
chadstr test1 = str("pineapple");
chadstr test1range = str((range)(test1, 3,6)); // eapp
/*
* If you are comfortable with range starting at index 1,
* #define HUMAN_RANGE before #include "chadstr.h"
* Note: negative end indices are still in "human" format
* starting at 1 no matter HUMAN_RANGE defined or not.
*/
#define HUMAN_RANGE
#include "chadstr.h"
...
chadstr test1 = str("pineapple");
chadstr test1range = str((range)(test1, 3,6)); // neap
Another example on generating random string with buffer and per char copying:
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "chadstr.h"
str random_string(size_t length)
{
chadstr pool = str("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
size_t randindex;
size_t i;
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
/* using nano-seconds instead of seconds */
srand((time_t)ts.tv_nsec);
char buffer[length+1];
for(i = 0; i < length; ++i)
{
randindex = rand() % pool->len;
buffer[i] = pool->data[randindex] ^ ((rand() % 2) ? 0 : 0x20);
}
buffer[i] = '\0';
return str(buffer);
}
int main(void)
{
for (int i = 0; i < 1000; ++i)
{
chadstr s = random_string(120);
puts(str(*s));
}
return 0;
}