does specman have static variables? - static

I have the following code in specman that I inherited:
some_method() is {
var a: bool;
if (!a) {
a = some_other_method();
};
};
My understanding is that each time some_method() is called, a is generated anew, and there's no sense in checking a's value before it's assigned. However, it may be that I'm missing something here. For instance, if a is static then this code makes sense, which brings me to my question:
Is there any way for a variable to be static in specman?

there are no static variables as in C. A variable in a method has its default value (False in this case) if not initialized, so you should be right if (!a) should always be True.
Things would be different if a was a struct member, then like in other OO languages it would retain there value over several method calls and the check would make more sense:
struct some_struct_s {
a : bool;
some_method() is {
if (!a) {
a = some_other_method();
};
};
};
You can check stuff like this also on the interactive prompt:
Specman> var a : bool;
Specman> print a
a = FALSE
There the interactive help is also nice, for example try:
Specman> help variable
and select the entry (by number) sn_eref: variables : declaring. There you will find all relevant information for your question.
Cheers,
Daniel

Static struct members (events, fields, methods) were added to the language in Specman v15.2. A static field can't be generated, physical(%) or used in when subtypes.
struct some_struct_s {
a : bool;
some_method() is {
if (!a) {
a = some_other_method();
};
};
};
-- Change field 'a' for all instances
on xxx { some_struct_s::a = TRUE; };
Here's some comments from the teamspecman blog : Static members in e

Related

How to get the class of a VALUE in Ruby C API

I created some classes with Ruby's C API. I want to create a function whose behavior will change depending on the class of the Ruby object.
I tried to use is_a? from Ruby, however, I don't think it's the good way to do this. I checked "Creating Extension Libraries for Ruby" without success. The only direct way to check classes is with the default types.
I have my class "Klass" already created:
VALUE rb_cKlass = rb_define_class("Klass", rb_cObject);
And how I wanted to check if the class is the good one:
VALUE my_function(VALUE self, VALUE my_argument) {
if(rb_check_class(my_argument), rb_cKlass)) {
// do something if my_argument is an instance of Klass
} else {
return Qnil;
}
}
Is there a way to do this?
I came across this recently, and used the RBASIC_CLASS macro, but was getting segfaults in certain scenarios for some unexplained reason.
After scanning through ruby.h, I found the CLASS_OF macro, which returns the class as VALUE of a given object.
VALUE obj = INT2NUM(10);
VALUE klass = CLASS_OF(obj); // rb_cInteger
Using Ruby 2.5
Every ruby object is internally represented by RObject struct (I will copy the source here for the sake of future readers):
struct RObject {
struct RBasic basic;
union {
struct {
uint32_t numiv;
VALUE *ivptr;
void *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
} heap;
VALUE ary[ROBJECT_EMBED_LEN_MAX];
} as;
};
The very first member, RBasic, defines the class:
struct RBasic {
VALUE flags;
const VALUE klass;
}
To get an access to RBasic metadata of anything, one might use RBASIC macro:
RBASIC(my_argument)
To get the class directly, one might use RBASIC_CLASS macro:
RBASIC_CLASS(my_argument)
If you want to stay close to the is_a? Ruby fashion (i.e. check if any of the ancestors is the expected class), you could directly use the C implementation of is_a?, rb_obj_is_kind_of:
rb_obj_is_kind_of(my_argument, rb_cKlass) // Qtrue OR Qfalse
And since Qfalse == 0, you can just use that method as a condition:
VALUE my_function(VALUE self, VALUE my_argument) {
if(rb_obj_is_kind_of(my_argument, rb_cKlass)) {
// do something if my_argument is an instance of Klass
} else {
return Qnil;
}
}
To find this method, just check Object#is_a? documentation and click to toggle source, you'll see the C implementation if it is a C function (hence this will work for most of the standard lib).

Specman e: How to use deep_copy on list of structs?

I have a my_list_1 (list of structs) that defined this way:
struct my_struct {
something[2] : list of int;
something_else[2] : list of uint;
};
...
my_list_1[10] : list of my_struct;
I need to copy this list to a local variable in a method:
foo_method() is {
var my_list_2 : list of my_struct;
my_list_2 = deep_copy(my_list_1);
...
};
The compilation error I get:
*** Error: 'my_list_1' is of type 'list of my_struct', while
expecting type 'any_struct'.
...
my_list_2 = deep_copy(my_list_1);
All variations to write deep_copy() I've tried caused compilation error... How to copy a list of structs to a local variable? Thank you for your help.
You can't use deep_copy(...) directly to copy a list. If you look in the docs, deep_copy(...) takes a single parameter of type any_struct and returns a single struct instance. You have to use it in a for each loop:
extend sys {
my_list_1[10] : list of my_struct;
run() is also {
foo_method();
};
foo_method() is {
var my_list_2 : list of my_struct;
for each (elem) in my_list_1 {
my_list_2.add(deep_copy(elem));
};
print my_list_1[0], my_list_2[0];
print my_list_1[1], my_list_2[1];
};
};
From Specman 14.2, deep_copy() will copy anything. I think it is not yet out, but due towards the end of this year.

How do I get class of a Ruby object in C?

I have a function that handles two types: NVector and NMatrix; the former is derived from the latter. This function is basically a specialized copy constructor. I want it to return an object of the same type as that upon which it was called, so, NVector returns NVector, not NMatrix.
static VALUE nm_init_modifiedcopy(VALUE self) {
// ... some code ...
// formerly, I had cNMatrix where klass is. But it could also be cNVector!
return Data_Wrap_Struct(klass, mark_func, delete_func, unwrapped_self_copy);
}
How do I get the class property of an object to pass into Data_Wrap_Struct?
Like clockwork, as soon as I ask a question on Stackoverflow, I find the answer.
The macro is CLASS_OF.
static VALUE nm_init_modifiedcopy(VALUE self) {
// ... some code ...
return Data_Wrap_Struct(CLASS_OF(self), mark_func, delete_func, unwrapped_self_copy);
}

More complex associative arrays in QT

Hi everybody and thanks for your time,
I read filenames in a QList. This is what I've done:
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFiles);
dialog.setViewMode(QFileDialog::Detail);
if(dialog.exec()) {
files.append(dialog.selectedFiles());
}
foreach(QString file, files) {
// add files to a table
}
I have all files in the QList files. Now I want the user to add information to this list. In PHP (or javascript) I would do something like this:
$fileinformation = array();
foreach($files AS $file) {
array_push($fileinformation, array (
'filename' => $file,
'doAction1' => false,
'doAction2' => true,
'parameter2' => array (
'value1' => $val1,
'value2' => $val2
)
)
)
}
And in the next step, I would make it possible for the user to edit the default options by editing $fileinformation['parameter2']['value']. But how can I do this in QT? I know, there are certain functions in qt like QList and QMap but both are not multidimensional and too unflexible for this case.
What did I miss?
You haven't missed anything. In a statically-typed language, you generally do not have objects of a completely different type all in the same container.
Assuming all of the parameters are defined at compile time, you can define a class or struct that contains those parameters and store it in a list. For brevity, I'm using a raw struct in this example. You may wish to explicitly initialize its members with a constructor and possibly wrap its data into a meaningful class.
struct FileInformation
{
QString filename;
bool doAction1;
bool doAction2;
struct ParameterStruct
{
QString value1; // I'm guessing it's QString, since you don't show what type it was.
QString value2;
} parameter2;
};
int main()
{
QList<FileInformation> myList;
FileInformation info;
info.fileName = "filename.txt";
info.doAction1 = false;
info.doAction2 = true;
info.parameter2.value1 = "someValue";
info.parameter2.value2 = "someOtherValue";
myList.append(info);
//now to change stuff!
myList[0].parameter2.value1 = "a new value";
}
It is possible to do this more akin to your example above (by nesting QVariantMaps), but that would be quite ugly, as C++'s static typing would demand manually casting at every access.

Defining setter return value

I just had a problem in one of my projects. Maybe I got the wrong concept about encapsulation.
Encapsulation protects member variables from classes, by defining getters and setters methods, now, i was reading that setters must be void, but in that case, how can I know if the function really set the value passed by argument. For example
void setArea(int a) {
if(a>0)
Area = a;
}
How can I be sure that argument "a" was a correct value, wouldnt be better defining the function like this
bool setArea(int a) {
if(a>0) {
Area = a;
return true;
}
return false;
}
Is that ok? that way i can know if a change really happened.
I think what you're looking for is a guard clause that throws an exception if invalid values are set:
void setArea(int a) {
if (a <= 0) throw new InvalidArgumentException(...);
Area = a;
}
But if you want client code to test for invalid values before setting them, you could have this:
bool isAreaValid(int a) {
return a > 0;
}
void setArea(int a) {
if (!isAreaValid(a)) throw new InvalidArgumentException(...);
Area = a;
}
Clients could be coded like this:
if (obj.isAreaValid(myArea)) {
obj.setArea(myArea);
}
But don't stop there. If the concept of area is important, spring it into existence into its own value object to make your design clearer.

Resources