antirez / sds

Simple Dynamic Strings library for C
BSD 2-Clause "Simplified" License
4.89k stars 473 forks source link

Enough awesome changes for a new version #101

Open easyaspi314 opened 5 years ago

easyaspi314 commented 5 years ago

I have been messing with sds recently, and I decided to submit my changes.

This is a summary of the changes:

The biggest feature is the new sdsadd macro. By far the best thing about this blob:

sds s = sdsempty();
s = sdsadd(s, "Hello");
s = sdsadd(s, "world");
s = sdsadd(s, '!');
s = sdsadd(s, ' ');
s = sdsadd(s, 1337);
puts(s);

Output> Hello, world! 1337

This is just like the += operator you find in Java/JavaScript/Ruby/std::string/QString/etc. It doesn't work with all compilers, but it has three implementations which have decent coverage:

Even if you can't use a compiler with at least one of those features, there are also the manual functions:

sds s = sdsempty();
s = sdscat(s, "Hello");
s = sdscat(s, "world");
s = sdsaddchar(s, '!');
s = sdsaddchar(s, ' ');
s = sdsaddint(s, 1337);
puts(s);

Output> Hello, world! 1337

Note that sdsadd will try its best to detect character literals, but it is impossible to catch them all without ridiculous compiler-dependent voodoo. The way to get sdsadd to recognize things is to make sure it is either explicitly the char type (either via a declaration or cast, signed/unsigned char are not guaranteed to work), or if the expression in the second macro argument lexically starts or ends in a single quote. The macro that detects the latter case is this:

#define SDS_IS_CHAR(x) ((#x[0] == '\'') || (sizeof(#x) > 3 && #x[sizeof(#x) - 2] == '\''))

Note: that check is optimized away at compile time, so don't worry about extra runtime checks.

As long as your statement matches that and is convertible to char, int, or unsigned int, it will match. It works about 90% of the time.

Other features:

Documentation is coming soon, as well as more pedantic error checking (a debug mode?)