These are functions for several uses throughout other LI toolboxes, but some also make use of each other. Here some examples for every category are given.
Matlab® already comes with an awful lot of string and file path handling, but in some cases addons seemed to still be an improvement. One example is the right to read, write or create files. Using fileattrib you will get some flags for MS Windows, that are mostly meaningless on any NTFS file system, while for Unix/Linux you get read/write/execute flags, that won't tell you anything without file owner, file owner group, current user and current user's group memberships. So here comes li_fattrib with the approach to answer the basic questions of reading, writing and creating with respect to the user executing current script or command line.
So for a file named li.css that is assumed or needs to be created in the current directory, one can type
>> [sctAttribs, sNormPath, sNearest] = li_fattribs('li.css') sctAttribs = exists: 0 isAbsolute: 0 isNameOnly: 1 isDir: 0 isFile: 0 isSymLink: 0 isReadOnly: 0 isHidden: 0 userCanRead: 0 userCanWrite: 0 sNormPath = D:\LI\li_ml\common\c\li.css sNearest = D:\LI\li_ml\common\c
and gets the basic information to go on with programming. As much as possible the underlying mex function makes use of the C++ boost library filesystem, and where it comes to file privileges the respective OS's API is questioned.
If a Simulink® block path should be split considering its escape rules, the task can be done with a single call:
>> li_splitbp('mysys/mysubsys//with//slashes/someblock') ans = 'mysys' 'mysubsys/with/slashes' 'someblock'
See also the function list for the category.
This category focusses on input parameter validation and normalisation. While Matlab® provides some means to at least validify the number of inputs and outputs of a function, checking types is a lengthy task, that often gets reduced to a bare minimum, if any, and leads to nasty error messages and debugging.
Given a function with input parameters a and b, where a is supposed to represent a Simulink® block and b a file to be read from, the following code can be used:
[sErr, a] = li_ckvar(a, 'sl-obj', '--scalar-only', true, '--ret-type', 'handle', '--sl-type', 'block', '--var-name', '1st input a'); error(sErr); [sErr, b] = li_ckvar(b, 'file-read', '--return-type', 'char', '--var-name', '2nd input b'); error(sErr);
Here a will be normalised to the repective handle in case of an existing (loaded) blockpath, the handle itself will be used in case of a valid handle of type block, and an error message will be raised that describes allowed inputs as well as a description of the type actually found in all other cases. b will be a row vector of type char representing the canonicalised path of the file, if passed b is any kind of string representation, that points to a file readable by the current user, and an error message will be raised that describes allowed inputs as well as a description of the type actually found in all other cases.
See also the function list for the category.
Simulink® helper functions are made up to analyse the signal flow within models. The ouport of a block might be followed to all destinations and an inport to its source, all with different scopes and conditions. Also signal loop detection is possible for different scopes of search.
In the following example from a test purpose model
One might use the editor feature "Highlite to Destination" to see all destinations of the example model's signal sissi emanating from a constant block at te top left. But for one thing the destination ports are not accessible by script (at least with less recent releases), and for the other any signal lines containing the signal in a bus are hightlighted, even if it is never extraxted from the bus:
With the use of li_getsigdsts the one true destination (or multiple in other cases) is returned, the inport handle of the terminator block Terminator1:
>> sctPortHdls = get_param('ff_3/Constant1', 'PortHandles'); >> jDsts = java.util.ArrayList(); >> li_getsigdsts(sctPortHdls.Outport, jDsts); >> getfullname(jDsts.get(0)) ans = ff_3/Terminator1/<sissi> >> hilite_system(jDsts.get(0))
By the strict use of handles rather than block paths and java dynamic arrays that do not reallocate memory on every added element and are passed by handle, the functionset is quick even when analysing large systems.
See also the function list for the category.