sysutils.CharInSet
- Type: feature (compat — FPC/Delphi RTL function absent) — Track B
(
lib/rtl/sysutils.pas).
function CharInSet(Ch: AnsiChar; const CSet: TSysCharSet): Boolean;
begin
Result := Ch in CSet;
end;
The one-line body is the whole function in FPC too; it exists for the Delphi
WideChar overload's sake, not for the AnsiChar one.
Why it is filed rather than fixed on the spot
Found by Track P while cutting pparser.pp down to localise a parse error — it
is behind two parse walls and cannot be reached by compiling the unit today, so
nothing here has been measured end-to-end. The declaration is trivial; what
is not established is whether pxx's TSysCharSet and its in operator accept
this exact shape, and a one-line addition that compiles is not evidence the call
site works. Whoever takes it should drive it from a program, not build it.
Gate
Assert a value on BOTH answers — CharInSet('A', ['A'..'Z']) true and
CharInSet('a', ['A'..'Z']) false. A predicate that returns a constant passes a
one-row test, and the failure mode here (an empty or mis-built set) is exactly
the one that returns the same answer for every character.
Resolution — 2026-09-06
Both landed together. CharInSet is the one-liner the ticket predicted;
AnsiDequotedStr is not, and its three non-obvious cases are FPC's behaviour
rather than choices, so each has its own row:
- a string that does not start with the quote is returned WHOLE and
unexamined —
ab'cdkeeps its inner quote. An implementation that "strips quotes wherever it finds them" passes every other row and fails this one. - a doubled quote is an escape:
'ab''c'isab'c. - an unterminated quote consumes to the end rather than raising.
I would have got at least the first of those wrong from reading FPC's source —
it falls out of AnsiExtractQuotedStr's exit(strpas(P)) rather than being
stated anywhere — which is the reason every row is compared against the running
fpc binary and not against my reading of it.
Written over the string rather than over a PChar cursor: FPC's var Src: PChar
exists so AnsiExtractQuotedStr can report where it stopped, and nothing here
has that caller. If one appears, add AnsiExtractQuotedStr beside it rather
than reshaping this.
The gate this ticket asked for — assert BOTH answers of the predicate — is met, plus the empty set, because the failure mode named here (an empty or mis-built set) returns the same answer for every character.
Log
- 2026-09-06 — fixed, commit ffefbeeb3.