Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

## 4.0.19 - 3rd 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;
* Treated a lone CR (not followed by LF, including CR at end of stream) as a line terminator that returns `CSTRING_RC_SUCCESS` and pushes the following character back;
* Added single-line LF, CRLF, and CR cases to **test.component.cstring_readline**; **test.component.cstring_vector_readLines** splits an embedded CR into its own line;
* Passed `temp_file::CloseOnOpen` in **test.component.cstring_readline** so the creating handle is closed before `fopen`, which Windows otherwise rejects as a sharing violation;
* `cstring_readline()` returns the result of its opening `cstring_truncate()`, so a readonly destination yields `CSTRING_RC_READONLY` for an empty line or immediate end of file, and the payload and stream position are left unchanged;
* Added **test.component.cstring_readline** case `TEST_cstring_readline_READONLY_RETAINS_PAYLOAD`;

Expand Down
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
| Date | News Item | Details |
| ------------------- | -------------------------------- | ------- |
| Available from [**cstring** project on GitHub](https://synesissoftware.com/cstring): |
| 3rd October 2026 | Release of [cstring 4.0.19](https://github.com/synesissoftware/cstring/releases/tag/4.0.19) | `cstring_readline()` reports a failed readonly clear |
| 3rd October 2026 | Release of [cstring 4.0.19](https://github.com/synesissoftware/cstring/releases/tag/4.0.19) | lone CR ends a line; `cstring_readline()` `numRead` includes EOL; `cstring_readline()` reports failed readonly |
| 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 |
| 27th September 2026 | Release of [cstring 4.0.16](https://github.com/synesissoftware/cstring/releases/tag/4.0.16) | Phase 4b helpers, native `.cmd`, CI dogfood |
Expand Down
12 changes: 8 additions & 4 deletions include/cstring/cstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
# define CSTRING_VER_CSTRING_H_CSTRING_MAJOR 3
# define CSTRING_VER_CSTRING_H_CSTRING_MINOR 12
# define CSTRING_VER_CSTRING_H_CSTRING_REVISION 2
# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 91
# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 93
#endif /* !CSTRING_DOCUMENTATION_SKIP_SECTION */


Expand Down Expand Up @@ -827,17 +827,21 @@ cstring_swap(


/** Reads in a line of text from the given text stream
*
* A line ends at LF, at CRLF, or at a lone CR, including a CR at end of
* stream. The terminator is not stored. A lone CR pushes the next character
* back onto the stream;
*
* \param stm The stream from which the line will be read;
* \param pcs The initialised string instance into which the line will be
* stored;
* \param numRead An optional pointer to a variable to receive the number of
* characters appended to the string. May be NULL;
* characters read from the stream, including any terminator. May be NULL;
*
* \retval CSTRING_RC_INVALIDSTREAM The stream was not valid (as tested by
* <code>ferror()</code>);
* \retval CSTRING_RC_SUCCESS A line terminated by a carriage return was
* read in;
* \retval CSTRING_RC_SUCCESS A line terminated by CR, LF, or CRLF was read
* in;
* \retval CSTRING_RC_EOF A line terminated by the end-of-file was read in;
* \retval -other- Any other value returned by cstring_appendLen();
*
Expand Down
7 changes: 2 additions & 5 deletions run_all_component_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ Flags/options:
does not execute a build before running programs

--verbosity <verbosity>
specifies an explicit verbosity (forwarded when supported)
specifies an explicit verbosity, forwarded to each program


standard flags:
Expand Down Expand Up @@ -275,10 +275,7 @@ if [ $status -eq 0 ]; then
echo "executing ${fClr}:"
fi

if "$f" --verbosity="$Verbosity" 2>/dev/null; then

:
elif "$f"; then
if "$f" --verbosity="$Verbosity"; then

:
else
Expand Down
24 changes: 3 additions & 21 deletions run_all_examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}}
ListOnly=0
RunMake=1
SisUseColours=0
Verbosity=${XTESTS_VERBOSITY:-${TEST_VERBOSITY:-3}}


# ##########################################################
Expand Down Expand Up @@ -135,11 +134,6 @@ while [[ $# -gt 0 ]]; do

RunMake=0
;;
--verbosity)

shift
Verbosity=$1
;;
--help)

[ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt"
Expand All @@ -165,9 +159,6 @@ Flags/options:
--no-make
does not execute a build before running programs

--verbosity <verbosity>
specifies an explicit verbosity (forwarded when supported)


standard flags:

Expand Down Expand Up @@ -261,19 +252,10 @@ if [ $status -eq 0 ]; then
continue
fi

if [ $Verbosity -ge 3 ]; then

echo
fi
if [ $Verbosity -ge 2 ]; then

echo "executing ${fClr}:"
fi

if "$f" --verbosity="$Verbosity" 2>/dev/null; then
echo
echo "executing ${fClr}:"

:
elif "$f"; then
if "$f"; then

:
else
Expand Down
24 changes: 3 additions & 21 deletions run_all_performance_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ GapGroups=0
ListOnly=0
RunMake=1
SisUseColours=0
Verbosity=${XTESTS_VERBOSITY:-${TEST_VERBOSITY:-3}}


# ##########################################################
Expand Down Expand Up @@ -140,11 +139,6 @@ while [[ $# -gt 0 ]]; do

RunMake=0
;;
--verbosity)

shift
Verbosity=$1
;;
--help)

[ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt"
Expand Down Expand Up @@ -174,9 +168,6 @@ Flags/options:
--no-make
does not execute a build before running programs

--verbosity <verbosity>
specifies an explicit verbosity (forwarded when supported)


standard flags:

Expand Down Expand Up @@ -271,19 +262,10 @@ if [ $status -eq 0 ]; then
continue
fi

if [ $Verbosity -ge 3 ]; then

echo
fi
if [ $Verbosity -ge 2 ]; then

echo "executing ${fClr}:"
fi

if "$f" --verbosity="$Verbosity" 2>/dev/null; then
echo
echo "executing ${fClr}:"

:
elif "$f"; then
if "$f"; then

:
else
Expand Down
24 changes: 3 additions & 21 deletions run_all_scratch_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}}
ListOnly=0
RunMake=1
SisUseColours=0
Verbosity=${XTESTS_VERBOSITY:-${TEST_VERBOSITY:-3}}


# ##########################################################
Expand Down Expand Up @@ -135,11 +134,6 @@ while [[ $# -gt 0 ]]; do

RunMake=0
;;
--verbosity)

shift
Verbosity=$1
;;
--help)

[ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt"
Expand All @@ -165,9 +159,6 @@ Flags/options:
--no-make
does not execute a build before running programs

--verbosity <verbosity>
specifies an explicit verbosity (forwarded when supported)


standard flags:

Expand Down Expand Up @@ -257,19 +248,10 @@ if [ $status -eq 0 ]; then
continue
fi

if [ $Verbosity -ge 3 ]; then

echo
fi
if [ $Verbosity -ge 2 ]; then

echo "executing ${fClr}:"
fi

if "$f" --verbosity="$Verbosity" 2>/dev/null; then
echo
echo "executing ${fClr}:"

:
elif "$f"; then
if "$f"; then

:
else
Expand Down
7 changes: 2 additions & 5 deletions run_all_unit_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Flags/options:
accepted for compatibility; this script always runs unit tests only

--verbosity <verbosity>
specifies an explicit verbosity (forwarded when supported)
specifies an explicit verbosity, forwarded to each program


standard flags:
Expand Down Expand Up @@ -273,10 +273,7 @@ if [ $status -eq 0 ]; then
echo "executing ${fClr}:"
fi

if "$f" --verbosity="$Verbosity" 2>/dev/null; then

:
elif "$f"; then
if "$f" --verbosity="$Verbosity"; then

:
else
Expand Down
36 changes: 27 additions & 9 deletions src/cstring.core.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef CSTRING_USE_WIDE_STRINGS
# include <wchar.h>
#endif /* CSTRING_USE_WIDE_STRINGS */
Expand Down Expand Up @@ -1400,10 +1399,19 @@ cstring_readline(

if (EOF == ch)
{
if ('\r' == previous)
{
cstring_truncate(pcs, pcs->len - 1u);

return CSTRING_RC_SUCCESS;
}

return CSTRING_RC_EOF;
}
else
{
++*numRead;

if ('\n' == ch)
{
if ('\r' == previous)
Expand All @@ -1415,19 +1423,29 @@ cstring_readline(
}
else
{
cstring_char_t c1 = (char)ch;
CSTRING_RC rc = cstring_appendLen(pcs, &c1, 1u);

if (CSTRING_RC_SUCCESS != rc)
if ('\r' == previous)
{
return rc;
}
ungetc(ch, stm);

--*numRead;

++*numRead;
cstring_truncate(pcs, pcs->len - 1u);

return CSTRING_RC_SUCCESS;
}
else
{
cstring_char_t c1 = (char)ch;
CSTRING_RC rc = cstring_appendLen(pcs, &c1, 1u);

previous = ch;
if (CSTRING_RC_SUCCESS != rc)
{
return rc;
}
}
}

previous = ch;
}
}
}
Expand Down
Loading
Loading