How to check the text syntax of a Simulink model - matlab

I want to check if the mdl file of a Simulink model is syntactically correct or not. I don't want to load the model because I am only interested in the syntax errors, not the semantic issues (i.e. unconnected lines, etc.) Consider the example:
Model {
Name toy
System {
Name toy
Block {
BlockType DiscreteTransferFcn
Name "cfblk1"
}
Block {
BlockType Display
Name "cfblk2"
}
Line {
SrcBlock "cfblk1"
SrcPort 1
DstBlock "xyz"
DstPort 1
}
}
}
Here, the model is syntactically correct, but semantically the Line is not correct. Because there is no existing Block titled xyz. If I load the model then it will raise warnings:
Warning: sample.mdl, line 18: Attempt to set DstPort with invalid Destination
> In load_system (line 21)
Is there any way to validate the syntax of mdl files without loading them into memory?

Related

How to iterate over the unmapped registers of a bank in DML 1.4?

I am trying to migrate some modules to DML 1.4 and I face some problems during bank content iteration. Specifically, I originally have the snippet below:
select reg in ($signals.unmapped_registers) where (reg.signal_number == signal) {
// some statements here
} else {
log "unimplemented", 1: "Power/Board: Signal %d is unimplemented", signal;
return;
}
However, unmapped_registers is not valid in DML 1.4, thus leading to an unknown identifier compiler error.
How am I supposed to iterate over all the unmapped registers of a specific bank in DML 1.4 and select the one I want based on some specific criteria (i.e. the signal_number parameter)?
I've already tried swapping the select statement with foreach without success.
I've also tried to iterate over all bank registers that instantiate a specific template, but still without success.
You need to foreach over a template that has signal_number as type member.
When you iterate using foreach, the iteration variable is a run-time template reference, which means that not all declarations of the template can be accessed: Only parameters with a declared explicit type belong to the template type (together with all method declarations annotated with shared, and most session and saved declarations). So in your case, your problem is likely that signal_number does not have a declared type.
If you add a parameter type like this:
template register_with_signal is register {
param signal_number : int;
// default assignment must be a separate declaration
param signal_number default -1;
...
}
then you can implement your loop like this:
method handle_signal(int signal) {
foreach reg in (each register_with_signal in (this)) {
if (reg.signal_number == signal) {
// some statements here
return;
}
}
log unimpl: "signal %d is unimplemented", signal;
}

Get a source reference to all struct extensions in Specman

I am familiar with the collect command in Specman which returns all of the specified method's extensions. However, show source for a certain struct only returns the base struct definition and not all the extensions.
is there a command in Specman that is equivalent to collect but for structs/units?
there is no such command in Specman but since e is an incredibly flexible language you can add any command you may need using the powerful e macros.
For example, to implement what you want, you can create a macro that makes use of the reflection
Mechanism to get all layers of the desired struct and then print the relevant source lines:
define <struct_collect'command> "s_collect <any>" as {
var line_num:int;
var st:rf_struct = rf_manager.get_struct_by_name("<1>");
if (st==NULL) {
out(append("struct name does not exist : <1>"));
} else {
for each in st.as_a(rf_like_struct).get_layers() {
line_num=it.get_source_line_num();
out(append("In file ",it.get_module().get_name()," line ",line_num, " : ",files.get_text_lines(it.get_module().get_full_file_name(), line_num,line_num)));
};
};
};
you can improve on this macro, by writing the results to a file, or arrange it in a different way.
Cheers

Xtext linking service and derived state

I have this grammar:
Feature returns ecore::EStructuralFeature:
{Feature} name=ID ':' (fp_many?='*')? eType=[ecore::EClassifier];
And the EClass:
Class returns ecore::EClass:
{EClassClass}
name=ID (interface?=':Api')?
(BEGIN
(eStructuralFeatures+=Feature)*
(eOperations+=Operation)*
END)?;
My goal is to have a DSL for textual Ecore mm with a YAML like syntax, so I need to convert the Feature object depending on its EType to either an EAttribute or an EReference.
I have tried to hook the afterModelLinked in LazyLinker like this:
Queue<Feature> ftrs = Queues.newArrayDeque(features);
Feature f = null;
while ((f = ftrs.poll()) != null) {
if (f.getEType() == null)
continue;
if (f.getEType() instanceof EDataType) {
createEAttribute(eClazz, f);
} else if (f.getEType() instanceof EClass) {
createEReference(eClazz, f);
}
eClazz.getEStructuralFeatures().remove(f);
}
This code does converts the feature to the appropriate type but I get an error with the validation service an here the stack trace:
org.eclipse.emf.common.util.WrappedException: java.lang.NullPointerException
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:233)
at org.eclipse.xtext.resource.persistence.StorageAwareResource.getEObject(StorageAwareResource.java:124)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.doResolveLazyCrossReference(LazyLinkingResource.java:192)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.resolveLazyCrossReference(LazyLinkingResource.java:151)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.resolveLazyCrossReferences(LazyLinkingResource.java:137)
at org.eclipse.xtext.EcoreUtil2.resolveLazyCrossReferences(EcoreUtil2.java:528)
at org.eclipse.xtext.validation.ResourceValidatorImpl.resolveProxies(ResourceValidatorImpl.java:163)
at org.eclipse.xtext.validation.ResourceValidatorImpl.validate(ResourceValidatorImpl.java:75)
at org.eclipse.xtext.ui.editor.validation.ValidationJob$1.exec(ValidationJob.java:91)
at org.eclipse.xtext.ui.editor.validation.ValidationJob$1.exec(ValidationJob.java:1)
at org.eclipse.xtext.util.concurrent.CancelableUnitOfWork.exec(CancelableUnitOfWork.java:26)
at org.eclipse.xtext.resource.OutdatedStateManager.exec(OutdatedStateManager.java:121)
at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.internalReadOnly(XtextDocument.java:520)
at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.readOnly(XtextDocument.java:492)
at org.eclipse.xtext.ui.editor.model.XtextDocument.readOnly(XtextDocument.java:133)
at org.eclipse.xtext.ui.editor.validation.ValidationJob.createIssues(ValidationJob.java:86)
at org.eclipse.xtext.ui.editor.validation.ValidationJob.run(ValidationJob.java:67)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: java.lang.NullPointerException
at org.eclipse.xtext.linking.impl.ImportedNamesAdapter.find(ImportedNamesAdapter.java:34)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getImportedNamesAdapter(DefaultLinkingService.java:95)
at com.eacg.dsl.faml.linker.FamlLinkingService.getImportedNamesAdapter(FamlLinkingService.java:53)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.registerImportedNamesAdapter(DefaultLinkingService.java:86)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.registerImportedNamesAdapter(DefaultLinkingService.java:90)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.registerImportedNamesAdapter(DefaultLinkingService.java:80)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getScope(DefaultLinkingService.java:58)
at com.eacg.dsl.faml.linker.FamlLinkingService.getScope(FamlLinkingService.java:47)
at org.eclipse.xtext.linking.impl.DefaultLinkingService.getLinkedObjects(DefaultLinkingService.java:119)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:250)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:225)
When debugging I found that it's still using in context the object Feature even if I have removed it when I created the mapping.
My question is this: How to safely replace the object Feature without corrupting my model. I've also tried to implement IDerivedStateComputer but got the some error.
I think the underlying problem here is that EMF is a graph-based format; classes can be features of other classes, arguments to operations, etc. In general, this graph of relations can contain loops, cycles and knots. So anything that tries to modify things in-place is going to be tricky, requiring a full-blown graph traversal algorithm to make sure you don't change something depended on by something you haven't processed yet.
The alternative is to let the model load and link in it's native form, and then transform it as a single pass. This is the way xcore implements things; the equivalent declaration is:
XClass:
{XClass}
(annotations+=XAnnotation)*
((abstract?='abstract'? 'class') | interface?= 'interface') name = ID
('<' typeParameters+=XTypeParameter (',' typeParameters+=XTypeParameter)* '>')?
('extends' superTypes+=XGenericType (',' superTypes+=XGenericType)*)?
('wraps' instanceType=JvmTypeReference) ?
'{'
(members+=XMember)*
'}'
;
Note all the X's, those are local model classes. Then later on, there is just a function:
protected EClass getEClass(final XClass xClass)

How to pass parameters to a Progress program using database field dynamic-based rules?

I have in my database a set of records that concentrates information about my .W's, e.g. window name, parent directory, file name, procedure type (for internal treatments purposes), used to build my main menu. With this data I'm developing a new start procedure for the ERP that I maintain and using the opportunity in order to rewrite some really outdated functions and programs and implement new functionalities. Until now, I hadn't any problems but when I started to develop the .P procedure which will check the database register of a program that was called from the menu of this new start procedure - to check if it needs to receive fixed parameters to be run and its data types - I found a problem that I can't figure out a solution.
In this table, I have stored in one of the fields the parameters needed by the program, each with his correspondent data type. The problem is on how to pass different data types to procedures based only on the stored data. I tried to pre-convert data using a CASE clause and an include to check the parameter field for correct parameter sending but the include doesn't work as I've expected.
My database field is stored as this:
Description | DATATYPE | Content
I've declared some variables and converted properly the stored data into their correct datatype vars.
DEF VAR c-param-exec AS CHAR NO-UNDO EXTENT 9 INIT ?.
DEF VAR i-param-exec AS INT NO-UNDO EXTENT 9 INIT ?.
DEF VAR de-param-exec AS DEC NO-UNDO EXTENT 9 INIT ?.
DEF VAR da-param-exec AS DATE NO-UNDO EXTENT 9 INIT ?.
DEF VAR l-param-exec AS LOG NO-UNDO EXTENT 9 INIT ?.
DEF VAR i-count AS INT NO-UNDO.
blk-count:
DO i-count = 0 TO 8:
IF TRIM(programa.parametro[i-count]) = '' THEN
LEAVE blk-count.
i-count = i-count + 1.
CASE ENTRY(2,programa.parametro[i-count],CHR(1)):
WHEN 'CHARACTER' THEN
c-param-exec[i-count] = ENTRY(3,programa.parametro[i-count],CHR(1)).
WHEN 'INTEGER' THEN
i-param-exec[i-count] = INT(ENTRY(3,programa.parametro[i-count],CHR(1))).
WHEN 'DECIMAL' THEN
de-param-exec[i-count] = DEC(ENTRY(3,programa.parametro[i-count],CHR(1))).
WHEN 'DATE' THEN
da-param-exec[i-count] = DATE(ENTRY(3,programa.parametro[i-count],CHR(1))).
WHEN 'LOGICAL' THEN
l-param-exec[i-count] = (ENTRY(3,programa.parametro[i-count],CHR(1)) = 'yes').
OTHERWISE
c-param-exec[i-count] = ENTRY(3,programa.parametro[i-count],CHR(1)).
END CASE.
END.
Then I tried to run the program using an include to pass parameters (in this example, the program have 3 INPUT parameters).
RUN VALUE(c-prog-exec) ({util\abrePrograma.i 1},
{util\abrePrograma.i 2},
{util\abrePrograma.i 3}).
Here is my abrePrograma.i
/* abrePrograma.i */
(IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'CHARACTER' THEN c-param-exec[{1}] ELSE
IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'INTEGER' THEN i-param-exec[{1}] ELSE
IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'DECIMAL' THEN de-param-exec[{1}] ELSE
IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'DATE' THEN da-param-exec[{1}] ELSE
IF ENTRY(2,programa.parametro[{1}],CHR(1)) = 'LOGICAL' THEN l-param-exec[{1}] ELSE
c-param-exec[{1}])
If I suppress the 2nd, 3rd, 4th and 5th IF's from the include or use only one data type in all IF's (e.g. only CHAR, only DATE, etc.) the program works properly and executes like a charm but I need to call some old programs, which expects different datatypes in its INPUT parameters and using the programs as described OpenEdge doesn't compile the caller, triggering the error number 223.
---------------------------
Erro (Press HELP to view stack trace)
---------------------------
** Tipos de dados imcompativeis em expressao ou atribuicao. (223)
** Nao entendi a linha 86. (196)
---------------------------
OK Ajuda
---------------------------
Can anyone help me with this ?
Thanks in advance.
Looks as if you're trying to use variable parameter definitions.
Have a look at the "create call" statement in the ABL reference.
http://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dvref/call-object-handle.html#wwconnect_header
Sample from the documentation
DEFINE VARIABLE hCall AS HANDLE NO-UNDO.
CREATE CALL hCall.
/* Invoke hello.p non-persistently */
hCall:CALL-NAME = "hello.p".
/* Sets CALL-TYPE to the default */
hCall:CALL-TYPE = PROCEDURE-CALL-TYPE
hCall:NUM-PARAMETERS = 1.
hCall:SET-PARAMETER(1, "CHARACTER", "INPUT", "HELLO WORLD").
hCall:INVOKE.
/* Clean up */
DELETE OBJECT hCall.
The best way to get to the bottom of those kind of preprocessor related issues is to do a compile with preprocess listing followed by a syntax check on the preprocessed file. Once you know where the error is in the resulting preprocessed file you have to find out which include / define caused the code that won't compile .
In procedure editor
compile source.w preprocess source.pp.
Open source.pp in the procedure editor and do syntax check
look at original source to find include or preprocessor construct that resulted in the code that does not compile.
Okay, I am getting a little bit lost (often happens to me with lots of preprocessors) but am I missing that on the way in and out of the database fields you are storing values as characters, right? So when storing a parameter in the database you have to convert it to Char and on the way out of the database you have convert it back to its correct data-type. To not do it one way or the other would cause a type mismatch.
Also, just thinking out loud (without thinking it all the way through) wonder if using OOABL (Object Oriented ABL) depending on if you Release has it available wouldn't make it easier by defining signatures for the different datatypes and then depending on which type of input or output parameter you call it with, it will use the correct signature and correct conversion method.
Something like:
METHOD PUBLIC VOID storeParam(input cParam as char ):
dbfield = cParam.
RETURN.
END METHOD.
METHOD PUBLIC VOID storeParam(input iParam as int ):
dbfield = string(iParam).
RETURN.
END METHOD.
METHOD PUBLIC VOID storeParam(input dParam as date ):
dbfield = string(dParam).
RETURN.
END METHOD.
just a thought.

Using Simulink Parameters in generated code

I use m file which initialize parameters in MATLAB workspace.
It is example of file:
Pconstant=Simulink.Parameter;
Pconstant.Value=3;
Pconstant.CoderInfo.StorageClass = 'exportedGlobal';
Pgain=Simulink.Parameter;
Pgain.Value=10;
Pgain.CoderInfo.StorageClass = 'exportedGlobal';
These parameters are used as value in 'Gain' and 'Constant' blocks. I generate c source code for this model and received following structure in model_data.c file:
/* Block parameters (auto storage) */
P_ParameterTest_T ParameterTest_P = {
10.0, /* Expression: Pgain
* Referenced by: '<Root>/Gain'
*/
3.0, /* Expression: Pconstant
* Referenced by: '<Root>/Constant'
*/
};
Model.h file contains following code:
/* Parameters (auto storage) */
struct P_ParameterTest_T_ {
real_T Gain_Gain; /* Expression: Pgain
* Referenced by: '<Root>/Gain'
*/
real_T Constant_Value; /* Expression: Pconstant
* Referenced by: '<Root>/Constant'
*/
};
Model source code compiling into model.a lib file which is used in other programs.
I can change value of constant in external c code:
parameters = (BLOCK_PARAMETERS*)rtmGetDefaultParam(model);
parameters->Constant_Value = 1;
But this solution is not good for me. Because I do not know where are used these parameters and I do not know fields names of structure.
Can I write code which will be set value in all fields of structure where are used Pconstant parameter? Something like this:
Pconstant = 1; //instead of parameters->Constant_Value = 1;
Thanks for help.
You say you have defined the storage class as ExportedGlobal but in the generated code, it appears as "auto storage", so something's not quite right there.
To achieve what you want, I think you need to turn "Inline parameters" on in the optimization pane (see documentation), and then click on the "Configure..." button to define which parameters you do not want inlined, i.e. Pconstant and Pgain (see the bit in the doc about inlining parameters). The structure construction you have in your code is normally used when "inline parameters" is turned off.
I'm guessing you have Simulink Coder, so you should also have a look in the Simulink Coder doc about how it generates code for parameters in different conditions. From memory, it's generally pretty thorough.