Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
902ab0b
general boilerplate / project-support improvements (#16)
synesissoftware Aug 9, 2026
ee3e693
squash-commit
synesissoftware Aug 9, 2026
4526cb5
4.0.14
synesissoftware Aug 9, 2026
52e55d8
fix
synesissoftware Aug 9, 2026
c5e1400
Merge branch 'master' into 'dev'
synesissoftware Aug 9, 2026
a1cc131
4.0.15 (#20)
mwsis Sep 6, 2026
5517777
markdown
synesissoftware Sep 16, 2026
72487c5
chore(c-cpp): union files.associations from ~/dev vscode settings
synesissoftware Sep 16, 2026
a708e89
.gitattributes
synesissoftware Sep 17, 2026
e140930
.vscode/settings.json
synesissoftware Sep 17, 2026
39738e2
.vimrc
synesissoftware Sep 17, 2026
c51736e
CHANGES.md
synesissoftware Sep 17, 2026
93fbbfa
chore(<lib>): use computed PREFIX_VER with documented PATCH
synesissoftware Sep 17, 2026
277e74f
test(<lib>): ship scratch libver version reporter
synesissoftware Sep 17, 2026
9a77dbb
test(<lib>): rename scratch libver to versions
synesissoftware Sep 17, 2026
bce400d
test: add canonical scratch versions reporter
synesissoftware Sep 17, 2026
a7fc836
.gitattributes
synesissoftware Sep 21, 2026
3948256
fix(c-cpp): quote Dir resolution in CMake helper scripts
synesissoftware Sep 21, 2026
6b044ee
Merge branch 'master' into 'dev'
synesissoftware Sep 22, 2026
27af964
Merge branch 'dev' into 'boilerplate'
synesissoftware Sep 22, 2026
6455ea4
chore(scratch test): **versions** => **test.scratch.version**
synesissoftware Sep 22, 2026
1c9819a
doc(README.md): adding afferent dependencies (**errni**, **rstrip**)
synesissoftware Sep 22, 2026
91c2b4b
feat(cstring): colour prepare_cmake and unify cmake configure
synesissoftware Sep 22, 2026
ad2a143
feat(cstring): force colours via env and -A in prepare_cmake
synesissoftware Sep 22, 2026
b121a6f
refactor(cstring): drive prepare builds with cmake --build
synesissoftware Sep 22, 2026
12078a7
refactor(cstring): drive build_cmake via cmake --build
synesissoftware Sep 22, 2026
e524810
refactor(cstring): drive clean_cmake via cmake --build --target clean
synesissoftware Sep 22, 2026
a078db8
refactor(cstring): align remove_cmake_artefacts with helper dialect
synesissoftware Sep 22, 2026
4f30aba
refactor(cstring): drive ctest_cmake via cmake --build then ctest
synesissoftware Sep 22, 2026
bc54b6e
refactor(cstring): unit/component runners use sis_cmake_build dialect
synesissoftware Sep 22, 2026
aa62ebb
fix(cstring): accept category-only flags; fix CI component runner
synesissoftware Sep 22, 2026
9e5083c
refactor(cstring): drive run_all_examples via cmake --build dialect
synesissoftware Sep 22, 2026
45bb3bb
fix(cstring): gate cstring_vector no-arg demo on SIS_EXAMPLE_SMOKE
synesissoftware Sep 22, 2026
d30ab59
refactor(cstring): drive run_all_scratch via cmake --build dialect
synesissoftware Sep 22, 2026
7e77034
refactor(cstring): native CMD runners for unit, component, examples
synesissoftware Sep 22, 2026
66fd7b4
feat(cstring): add run_all_automated_tests aggregate (.sh/.cmd)
synesissoftware Sep 22, 2026
b54e4c6
refactor(cstring): drive run_all_performance via cmake --build dialect
synesissoftware Sep 22, 2026
b0b25cd
style(cstring): SisClr polish on run_all_automated_tests.sh
synesissoftware Sep 22, 2026
dbf5e80
ci(cstring): exercise prepare/build/clean helpers in CI
synesissoftware Sep 22, 2026
c95dc2d
ci(cstring): dogfood native run_all *.cmd on Windows cells
synesissoftware Sep 22, 2026
7ddfd90
ci(cstring): dogfood prepare/build in cells; order test jobs
synesissoftware Sep 22, 2026
f29cff5
ci(cstring): invoke ctest, remove, and automated helpers
synesissoftware Sep 22, 2026
fed0f53
fix(cstring): harden prepare empty-args and multi-config ctest
synesissoftware Sep 22, 2026
9f62cae
ci(cstring): dogfood run_all_automated_tests.cmd on Windows
synesissoftware Sep 22, 2026
6a622c2
ci(cstring): collapse cell suites into one post-build test job
synesissoftware Sep 22, 2026
57b6486
docs(cstring): target 4.0.16 release for 23 September 2026
synesissoftware Sep 23, 2026
47669c5
feat(cstring): add competitive performance tests for 4.0.17
synesissoftware Sep 23, 2026
205b5e3
test(cstring): time ifstream getline in the file-lines suite
synesissoftware Sep 23, 2026
5608670
test(cstring): pair borrowed_fixed_assign with std::string
synesissoftware Sep 23, 2026
031564c
prep
synesissoftware Sep 23, 2026
fb9b3f8
perf(cstring): copy known lengths with memcpy
synesissoftware Sep 23, 2026
6f7cde6
perf(cstring): grow vector inserts by 3/2
synesissoftware Sep 23, 2026
474547c
refactor(impl): simplification
synesissoftware Sep 23, 2026
836d67a
perf(cstring): free on destroy instead of realloc
synesissoftware Sep 23, 2026
aa357f7
fix(cstring): shift vector elements on insertAt
synesissoftware Sep 23, 2026
7e21244
perf(cstring): skip allocation for empty strings
synesissoftware Sep 23, 2026
c7f0082
perf(cstring): append in place when capacity fits
synesissoftware Sep 23, 2026
a78263f
refactor(impl): added common internal helper `cstring_vector_destroy_…
synesissoftware Sep 23, 2026
3686ada
refactor(impl): added common internal helper `cstring_vector_init_emp…
synesissoftware Sep 23, 2026
ecb49fa
tidying
synesissoftware Sep 26, 2026
d26faab
squash-commit
synesissoftware Sep 26, 2026
14fbc4f
squash-commit
synesissoftware Sep 27, 2026
818eff0
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 27, 2026
8b3e261
Perf tests (#22)
mwsis Sep 27, 2026
cc85bf7
More component tests (#23)
synesissoftware Sep 27, 2026
589c51f
fix
synesissoftware Sep 27, 2026
f17597a
Flags fixes (#24)
synesissoftware Sep 27, 2026
eb9fd45
squash-commit
synesissoftware Sep 27, 2026
7783fc2
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 27, 2026
d0840e6
version
synesissoftware Sep 27, 2026
d302239
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 27, 2026
91e63f1
chore: trivial ordering
synesissoftware Sep 27, 2026
9dd8d4c
TODO.md
synesissoftware Sep 27, 2026
aa0b4e0
TODO.md
synesissoftware Sep 27, 2026
0af6b71
fix
synesissoftware Sep 27, 2026
9da3ff7
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 27, 2026
8606170
fix
synesissoftware Sep 27, 2026
85c52c8
fix(cstring): gate Windows arenas on `_WIN32` for 4.1.0 (#25)
synesissoftware Sep 29, 2026
864bdb5
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 29, 2026
def3924
test(cstring): time Windows global, process-heap, and COM task arenas…
synesissoftware Sep 29, 2026
87eb7f8
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 29, 2026
2c16779
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 29, 2026
e7be85e
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 29, 2026
e18e915
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 29, 2026
def0488
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 29, 2026
72ef8b8
fix(cstring): initialise COM before Windows task-allocator tests
synesissoftware Sep 29, 2026
656523b
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 29, 2026
f88daf1
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Sep 30, 2026
74ece39
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Oct 3, 2026
41319ff
feature(performance tests): added `scenario_append_len_inc8()`
synesissoftware Oct 3, 2026
476da2a
Merge branch 'dev' into 'perf-optimisations'
synesissoftware Oct 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# cstring - Changes <!-- omit in toc -->


## 4.2.0 - 6th October 2026

* performance optimisations;


## 4.0.19 - 4th October 2026

* Corrected `cstring_readline()` so `numRead` counts every character read from the stream for the line, including the terminator; CR and LF are not stored;
Expand Down
2 changes: 1 addition & 1 deletion Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

PROJECT_NAME = "cstring"
PROJECT_BRIEF = "Extensible C-style strings and vectors of such, for Unix and Windows"
PROJECT_NUMBER = 4.0.19
PROJECT_NUMBER = 4.2.0

# Prefer SIS_CMAKE_BUILD_DIR-aligned output (same convention as Diagnosticism).
# ./dox/ remains gitignored for legacy/local runs that override OUTPUT_DIRECTORY.
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
| Date | News Item | Details |
| ------------------- | -------------------------------- | ------- |
| Available from [**cstring** project on GitHub](https://synesissoftware.com/cstring): |
| 5th October 2026 | Release of [cstring 4.2.0](https://github.com/synesissoftware/cstring/releases/tag/4.2.0) | Performance optimisations |
| 4th October 2026 | Release of [cstring 4.0.19](https://github.com/synesissoftware/cstring/releases/tag/4.0.19) | lone CR ends a line; `numRead` includes EOL; readonly truncate; zero-size realloc frees; **test.performance.cstring_readline**; shortened test and example directories; **test.unit.cstring**; README usage modes |
| 29th September 2026 | Release of [cstring 4.0.18](https://github.com/synesissoftware/cstring/releases/tag/4.0.18) | `_WIN32` arena gate; **win.c**; static `CoTaskMem*` (**ole32**) |
| 29th September 2026 | Release of [cstring 4.0.17](https://github.com/synesissoftware/cstring/releases/tag/4.0.17) | Perf tests; `insertAt` fix; component I/O; Windows arena rename |
Expand Down
7 changes: 4 additions & 3 deletions include/cstring/cstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
# define CSTRING_VER_4_0_17 0x040011ff
# define CSTRING_VER_4_0_18 0x040012ff
# define CSTRING_VER_4_0_19 0x040013ff
# define CSTRING_VER_4_2_0_A1 0x04020041
#endif /* !CSTRING_DOCUMENTATION_SKIP_SECTION */

/** \def CSTRING_VER_MAJOR
Expand All @@ -123,9 +124,9 @@
*/

#define CSTRING_VER_MAJOR 4
#define CSTRING_VER_MINOR 0
#define CSTRING_VER_PATCH 19
#define CSTRING_VER_ALPHABETA 0xFF
#define CSTRING_VER_MINOR 2
#define CSTRING_VER_PATCH 0
#define CSTRING_VER_ALPHABETA 0x41

#define CSTRING_VER \
(0\
Expand Down
2 changes: 1 addition & 1 deletion include/cstring/cstring.vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Purpose: Definition of the cstring.vector API.
*
* Created: 21st January 2012
* Updated: 28th September 2026
* Updated: 29th September 2026
*
* Home: http://synesis.com.au/software/
*
Expand Down
196 changes: 148 additions & 48 deletions src/cstring.core.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,10 @@ convert_negative_index_(
* \param src Source. May be \c NULL;
* \param lim Maximum number of elements in \c dst;
*
* \return The actual length of src if not \c NULL; 0 otherwise
*
* \pre NULL != dst
*/
static
size_t
void
cstring_strlcpy_safe_(
cstring_char_t dst[]
, cstring_char_t const* src
Expand All @@ -186,30 +184,10 @@ cstring_strlcpy_safe_(
if (NULL == src)
{
memset(dst, 0, sizeof(cstring_char_t) * lim);

return 0;
}
else
{
size_t i;

for (i = 0; i != lim; ++i, ++dst, ++src)
{
*dst = *src;

if ('\0' == src[0])
{
break;
}
}

memset(dst, 0, sizeof(cstring_char_t) * (lim - i));

for (; '\0' != src[0]; ++i, ++src)
{
}

return i;
memcpy(dst, src, sizeof(cstring_char_t) * lim);
}
}

Expand Down Expand Up @@ -287,7 +265,11 @@ cstring_realloc_2_(
*/
if (0 == cb)
{
free(pv);
if (NULL != pv)
{
free(pv);
}

return NULL;
}

Expand Down Expand Up @@ -359,6 +341,31 @@ cstring_realloc_(
return cstring_realloc_2_(pv, cch, flags, prc, NULL, NULL);
}

/** Releases owned storage and leaves \c pcs empty with a NULL pointer. */
static
CSTRING_RC
cstring_release_to_empty_(
struct cstring_t* pcs
)
{
CSTRING_RC rc = CSTRING_RC_SUCCESS;

CSTRING_ASSERT(NULL != pcs);

if (!(CSTRING_F_MEMORY_IS_BORROWED & pcs->flags) &&
NULL != pcs->ptr)
{
(void)cstring_realloc_(pcs->ptr, 0, pcs->flags, &rc);
}

pcs->len = 0;
pcs->ptr = NULL;
pcs->capacity = 0;
pcs->flags = 0;

return rc;
}


/* /////////////////////////////////////////////////////////////////////////
* API
Expand Down Expand Up @@ -469,7 +476,17 @@ cstring_create(

CSTRING_ASSERT(NULL != pcs);

cch = (0 == len) ? 1u : len;
if (0 == len)
{
pcs->len = 0;
pcs->ptr = NULL;
pcs->capacity = 0;
pcs->flags = 0;

return CSTRING_RC_SUCCESS;
}

cch = len;
cch = (cch + (CSTRING_ALLOC_GRANULARITY - 1)) & ~(CSTRING_ALLOC_GRANULARITY - 1);

pcs->ptr = (cstring_char_t*)cstring_realloc_(NULL, cch + 1, 0, &rc);
Expand Down Expand Up @@ -503,7 +520,17 @@ cstring_createLen(

CSTRING_ASSERT(NULL != pcs);

cch = sizeof(cstring_char_t) * ((0 == len) ? 1u : len);
if (0 == len)
{
pcs->len = 0;
pcs->ptr = NULL;
pcs->capacity = 0;
pcs->flags = 0;

return CSTRING_RC_SUCCESS;
}

cch = len;
cch = (cch + (CSTRING_ALLOC_GRANULARITY - 1)) & ~(CSTRING_ALLOC_GRANULARITY - 1);

pcs->ptr = (cstring_char_t*)cstring_realloc_(NULL, cch + 1, 0, &rc);
Expand Down Expand Up @@ -644,6 +671,16 @@ cstring_createLenFn(
pcs->ptr = (cstring_char_t*)arena;
pcs->capacity = capacity - 1;
}
else if (0 == len &&
0 == capacity)
{
pcs->len = 0;
pcs->ptr = NULL;
pcs->capacity = 0;
pcs->flags = 0;

return CSTRING_RC_SUCCESS;
}
else
{
size_t cch;
Expand Down Expand Up @@ -681,21 +718,9 @@ cstring_destroy(
struct cstring_t* pcs
)
{
CSTRING_RC rc = CSTRING_RC_SUCCESS;

CSTRING_ASSERT(NULL != pcs);

if (!(CSTRING_F_MEMORY_IS_BORROWED & pcs->flags))
{
(void)cstring_realloc_(pcs->ptr, 0, pcs->flags, &rc);
}

pcs->len = 0;
pcs->ptr = NULL;
pcs->capacity = 0;
pcs->flags = 0;

return rc;
return cstring_release_to_empty_(pcs);
}

#ifndef CSTRING_OBSOLETE
Expand Down Expand Up @@ -896,12 +921,30 @@ cstring_assignFn(
{
const size_t len = cstring_strlen_safe_(s);

if (0 == len)
{
if (NULL != pcs->ptr)
{
pcs->len = 0;
pcs->ptr[0] = '\0';

return CSTRING_RC_SUCCESS;
}

pcs->len = 0;
pcs->ptr = NULL;
pcs->capacity = 0;
pcs->flags = 0;

return CSTRING_RC_SUCCESS;
}

if (0 == pcs->capacity ||
pcs->capacity < len)
{
size_t cch;

cch = (0 == len) ? 1u : len;
cch = len;
cch = (cch + (CSTRING_ALLOC_GRANULARITY - 1)) & ~(CSTRING_ALLOC_GRANULARITY - 1);

if (cch < pcs->capacity * 2)
Expand Down Expand Up @@ -996,12 +1039,30 @@ cstring_assignLenFn(
}
else
{
if (0 == len)
{
if (NULL != pcs->ptr)
{
pcs->len = 0;
pcs->ptr[0] = '\0';

return CSTRING_RC_SUCCESS;
}

pcs->len = 0;
pcs->ptr = NULL;
pcs->capacity = 0;
pcs->flags = 0;

return CSTRING_RC_SUCCESS;
}

if (0 == pcs->capacity ||
pcs->capacity < len)
{
size_t cch;

cch = (0 == len) ? 1u : len;
cch = len;
cch = (cch + (CSTRING_ALLOC_GRANULARITY - 1)) & ~(CSTRING_ALLOC_GRANULARITY - 1);

if (cch < pcs->capacity * 2)
Expand Down Expand Up @@ -1108,7 +1169,23 @@ cstring_appendFn(
size_t const len = cstring_strlen_safe_(s);
size_t const newLen = pcs->len + len;

if (pcs->capacity < newLen)
if (0 == len)
{
return CSTRING_RC_SUCCESS;
}

/* Capacity already covers the write: copy in place. */
if (pcs->capacity >= newLen)
{
CSTRING_ASSERT(NULL != pcs->ptr);

cstring_memcpy_safe_(pcs->ptr + pcs->len, s, len * sizeof(cstring_char_t));
pcs->len = newLen;
pcs->ptr[pcs->len] = '\0';

return CSTRING_RC_SUCCESS;
}

{
size_t cch;

Expand Down Expand Up @@ -1214,13 +1291,29 @@ cstring_appendLenFn(
}
else
{
size_t newLen = pcs->len + len;
size_t const newLen = pcs->len + len;

if (0 == len)
{
return CSTRING_RC_SUCCESS;
}

/* Capacity already covers the write: copy in place. */
if (pcs->capacity >= newLen)
{
CSTRING_ASSERT(NULL != pcs->ptr);

cstring_memcpy_safe_(pcs->ptr + pcs->len, s, len * sizeof(cstring_char_t));
pcs->len = newLen;
pcs->ptr[pcs->len] = '\0';

return CSTRING_RC_SUCCESS;
}

if (pcs->capacity < newLen)
{
size_t cch;

cch = pcs->len + len;
cch = newLen;
cch = (cch + (CSTRING_ALLOC_GRANULARITY - 1)) & ~(CSTRING_ALLOC_GRANULARITY - 1);

if (cch < pcs->capacity * 2)
Expand Down Expand Up @@ -1285,7 +1378,7 @@ cstring_appendLenFn(
}
}

cstring_strlcpy_safe_(pcs->ptr + pcs->len, s, len);
cstring_memcpy_safe_(pcs->ptr + pcs->len, s, len * sizeof(cstring_char_t));
pcs->len += len;
pcs->ptr[pcs->len] = '\0';

Expand Down Expand Up @@ -1373,6 +1466,8 @@ cstring_readline(
numRead = &dummy;
}

*numRead = 0u;

if (NULL == stm ||
0 != ferror(stm))
{
Expand Down Expand Up @@ -1477,7 +1572,12 @@ cstring_write_(

*numWritten = 0u;

r = fprintf(stm, fmt, (int)pcs->len, pcs->ptr);
r = fprintf(
stm
, fmt
, (int)pcs->len
, (NULL != pcs->ptr) ? pcs->ptr : ""
);

if (r < 0)
{
Expand Down
Loading
Loading