Upgrading to 1.10.0
partitionfollows Pythonstr.partition. If the separator is not found the parts are the string and two null strings: the second part was the separator, so a caller could not tell whether it was found. A separator as long as the string, or longer, is searched too:'ab'%partition('ab')gives'','ab',''(it gave'ab','ab','').- Assigning a part of a string to the string itself (
astring = astring%raw(2:)) read freed memory and could give wrong data, depending on the platform; it is now safe.
Upgrading to 1.9.0
Release 1.9.0 reads UTF-8 text as characters (Unicode and UTF-8). On ASCII text nothing changes. On non-ASCII text the methods that worked on single bytes now work on units, a unit being a well-formed UTF-8 sequence or a byte that is not part of one:
reversekeeps the bytes of each character in order:'ab'followed byéreverses toéthen'ba', it gave invalid UTF-8.match:?and a class[...]match one character,'caf?'matchescafé; a range compares codepoints.scan,verify,strip/lstrip/rstripwithremove=,squeezewith a set take a set of characters:ãno longer matches the seté(they share their first byte), and a backwardverifygives the first byte of a character, not its last one.squeezereduces runs of a repeated non-ASCII character, which it did not see.transliteratemaps characters to characters, soold_setandnew_setcan hold non-ASCII ones and the result can be longer than the string.
Bytes that are not well-formed UTF-8 (Latin-1 text, binary data) are units on their own and keep their old behaviour. The only difference for them is Latin-1 or binary content that happens to contain a well-formed sequence (the Latin-1 é is the bytes C3 A9, é in UTF-8): that pair is now one unit.
Two defects are fixed too: split_chunked crashed on a string made only of separators, it now gives no tokens as split does; end_with read one byte before a null string.
Upgrading to 1.4.0
Release 1.4.0 makes the string methods linear in time and memory and fixes their edge cases. Three changes can alter the results of existing programs:
replaceis not recursive. The replaced text is not searched again, as in Pythonstr.replace:'aaaa'with'aa'replaced by'a'gives'aa'(it gave'a'), and anewcontainingoldno longer loops forever.count=0replaces nothing (it replaced one occurrence).- Unformatted I/O of a
stringstores its length.write(unit) astringwrites the length (anI8Pinteger) then the characters, andreadreads them back exactly; strings were truncated at 100 characters. Unformatted files written by an earlier version are not readable. - Defined results on edge cases.
to_numberon a string that is not a number gives 0 (integer kinds) or a quiet NaN (real kinds), it was undefined;splitof a string made only of separators gives no tokens, it gave the string itself;count(of characters) no longer undercounts;count('')andunique('')no longer loop forever.
Changelog
All notable changes to this project are documented here. Versions follow Semantic Versioning. Format follows Keep a Changelog.
[1.11.0] — 2026-10-31
Added
regex: Regular expressions, a Pike VM linear in the subject
regex: Finditer, findall, split, sub and the re_* procedures
Documentation
regex: Regular expressions guide, tutorial chapter and recipes
readme: Regular expressions and UTF-8 in the features
[1.10.0] — 2026-10-30
Added
utf8: Positions and lengths in characters with by=SF_CHARS
utf8: Slice, insert and len_last_word in characters with by=SF_CHARS
utf8: Widths in characters with by=SF_CHARS
utf8: Display width in terminal columns
xml: Escape_xml, unescape_xml and xml_error
utf8: Unicode whitespace with unicode=.true.
sort: Strsort and the orders strless, strless_nocase, strless_natural
Documentation
utf8: Positions and widths in characters
utf8: Display width, and its differences from wcwidth
xml: XML escaping
utf8: Unicode whitespace
sort: Sorting arrays of strings
Fixed
string_t: Assigning a part of a string to itself
string_t: Partition as Python str.partition ⚠ BREAKING CHANGE
[1.9.1] — 2026-10-30
Fixed
- io: Use-after-free in the module read_lines with skip_bom
[1.9.0] — 2026-10-30
Added
unicode: Generate the Unicode property tables from the UCD
utf8: Add the UTF-8 core: validation, codepoints and repair
escape: Add the C escape codecs escape_c, unescape_c and escapes_error
utf8: Scan, verify and strip work on units
utf8: Reverse, squeeze and transliterate work on units
utf8: Match wildcard patterns by units
io: Read and write the UTF-8 byte order mark
Documentation
Add searching to the tutorial, unit, binary and stdin recipes
utf8: Document the methods that work on units, add the 1.9.0 upgrade notes ⚠ BREAKING CHANGE
Fixed
ci: Run install smoke test from the release workflow
string_t: Split_chunked without tokens, end_with on a null string
Performance
- utf8: ASCII fast paths for the methods that work on units
[1.8.0] — 2026-10-04
Added
- string_t: Fast exact number casting, count/index/strip options
Documentation
- Cover the new methods in tutorial, cookbook and home pages
[1.7.0] — 2026-10-04
Added
- string_t: Add character classes, tr-like and padding methods
[1.6.0] — 2026-10-03
Added
- string_t: Add read_number with an error status, keep empty fields in split
[1.5.0] — 2026-10-03
Added
- string_t: Add match of wildcard patterns, make glob safe
[1.4.0] — 2026-10-03
Documentation
- Add the 1.4.0 upgrade notes, sync run_tests.sh and release.sh
Performance
- string_t: Make split, replace, unique, escape, join and read_* linear
[1.3.1] — 2026-10-03
Changed
- cmake: Find PENF and FACE by their standard config names
Fixed
makefile: Repair the make build and keep the doctests in sync
cmake: Make the installed package usable by find_package
string_t: Return a not allocated string for an unknown codec
release: Sync fpm.toml version on release, unblock docs build
[1.3.0] — 2026-10-02
Added
- string_t: Add six string methods from the issue #3 wishlist
Documentation
- Rebuild README and site on compiled examples, fix I/O bugs
Fixed
string_t: Prevent out-of-bounds on blank and null strings
fobos: Repair makecoverage rule and adopt double-dash fobis CLI
string_t: Correct is_real and base64 decode, extend slice/strip
[1.2.0] — 2026-10-02
Fixed
docs: Untrack package-lock and pin esbuild for lock-free vite build
string_t: Guard R16P generic bindings with PENF_R16P macro
[1.1.6] — 2026-02-18
Fixed
- docs: Correct project name casing to StringiFor throughout
[1.1.5] — 2026-02-18
Documentation
- Add VitePress site, rework CI/CD, and refactor README
[1.1.4] — 2026-02-18
Fixed
- Fix GNU gfortran issue with recursive procedure