String Contains — Control Systems/Strings
Control_Systems/Strings/String_Contains · 2 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
String Contains
Control Systems / Strings
Asks whether one piece of text occurs inside another and answers with a true/false signal: y = (u2 occurs in u1). Choose whether it may occur anywhere, only at the start, or only at the end.
Ports
- u1 (
str,ICoreString) – the text being searched. - u2 (
str,ICoreString) – the text being looked for. - Output (
bool,ICoreBool) – true when the test holds, false when it does not. One value.
Parameters
- Test – Contains is true when u2 occurs anywhere in u1; Starts with only when it occurs at the very beginning; Ends with only when it occurs at the very end.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Three library blocks, one block here
Simulink offers String Contains, String Starts With and String Ends With as three separate entries in its library, but they are one block with its Function setting preset three ways – the same dialog, the same ports, the same behaviour. This block is that block, and the Test parameter is that setting, so importing any of the three brings in this block already set to the right test.
Empty text
An empty u2 is true for all three tests: every piece of text starts with nothing, ends with nothing and contains nothing. An empty u1 is therefore true only when u2 is empty too. This matches what Simulink answers and it is what every generated target answers.
Upper and lower case are different
"Run" does not occur in "running". There is no option to ignore case, and that is deliberate rather than missing, for the reason set out on String Compare: "ignore case" would have to mean the same thing in the simulation and in all seven languages this block exports to, and their built-in case rules genuinely disagree with each other on anything that is not a plain A–Z letter. The whole Strings family gives one answer to that question rather than two.
Code export
C, C++, Python, MATLAB, Java and Rust all search the same bytes and produce the same true or false. Because the answer is a number rather than text, this block is also a way a text signal gets checked: an exported core that mishandled the text would produce a different true/false, and export verification compares that one exactly.
VHDL, Verilog and SystemVerilog do not carry text, and PLC Structured Text is not supported either: the language has a string type, but the check that runs an exported core cannot read one back. Since this block's inputs are always text, an export to any of these four stops and names this block and the reason.
Simulink bridge
Import and export, mapped to simulink/String/String Contains.
"Test" crosses as Function, whose three values are Simulink's own.
Simulink's case-sensitivity switch is always written as on, matching this block.
The Simulink block has no sampling-time setting of its own, so a positive
Sampling Time (s) stays on this side and is reported rather than
written.
Simulink searches characters where this block searches bytes. The two agree for any text that is plain ASCII, which is what the parity benches use; they disagree by design on text that is not, and that difference is here rather than hidden.
Notes
- Algebraic, with no state: the output depends only on the current inputs.
- An unconnected text input is empty text.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Strings/String_Contains |
| family | Control_Systems/Strings |
| solver environment class | ICoreBlock_0_Control_Systems_1_Strings_2_String_Contains |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Strings/String_Contains/ICoreBlock_0_Control_Systems_1_Strings_2_String_Contains.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Strings/String_Contains/ICoreBlock_0_Control_Systems_1_Strings_2_String_Contains.h |
| default size on canvas | 90 × 70 px |
| ports at insert | 2 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++ |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreString | u1 |
| 2 | in | ICoreString | u2 |
| 3 | out | ICoreBool | — |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
Test | Contains%~%Starts with%~%Ends with~~Contains | Function |
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::Both |
| Simulink path | simulink/String/String Contains |
| port-count rule | PortsParam:: |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Test | Function | passes through |
Caveat (shown to the user): simulink/String/String Starts With and String Ends With are THE SAME Simulink block as this one (all three measured BlockType=StringContains on R2026a, same two-parameter dialog), offered under two more library
Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The checker has a blind spot here — it could not resolve something (a grouped port bullet, a computed config name), which is reported and never counted as a pass. A reader has to settle it:
B0no sample under docs/generated/samples/ — nothing to cross-check (P8.1)
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
String Contains -- does one piece of text hold another, and where y = (u2 occurs in u1), with the config deciding whether it may occur anywhere, only at the start, or only at the end. One block, three Simulink library shortcuts: see the header for the R2026a measurement that folded them together, and for why the fold has to imply the Function preset rather than leave it at the canonical default.
Everything here searches BYTES of UTF-8, which is what makes the seven generated cores answer the same boolean as the simulator with no per-language special case: every one of the seven can look for one byte string inside another, and none of them has to agree about what a "character" is.
Sample results#
No sample run is committed for this block. Samples come from the headless harness (DOCS_PLAN.md P8.1) into docs/generated/samples/; until one exists this block's behaviour is witnessed by the parity and export-verification suites, not by a plot here.