Get a source reference to all struct extensions in Specman - 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

Related

How to find current package name from perl XS?

To get current context I find caller_cx function in perlapi. But there is no description for structure. In perl source code perl.h I can find only this typedef:
typedef struct context PERL_CONTEXT;
Is there examples how to use this struct returned by caller_cx to find current package from XS?
The context struct is defined cop.h as mentioned by #Dada in the comments:
struct context {
union {
struct block cx_blk;
struct subst cx_subst;
} cx_u;
};
also the block structures are defined in cop.h.
By inspecting the C implementation of the Perl caller function in pp_ctl.c (line 1850), I think you can get the package name using the following code:
const PERL_CONTEXT *cx = caller_cx(0, NULL);
char *pack_name = HvNAME((HV*)CopSTASH(cx->blk_oldcop));

How to create a macro to create an array of structs?

Given a struct Foo:
struct Foo<'a> {
info: &'a str
}
To create an array of Foos with different strings inside, I would like to have a macro, which could be used like:
assert_eq!(make_foo!("test"; 2), [Foo { info: "test 1" }, Foo { info: "test 2" }]);
What I am confused about specifically is how to iterate over the specific number of times as specified in the second argument.
Currently, to the best of my knowledge, it's impossible to create a macro which works exactly as you wish. It's only kind of possible. I'll explain:
First, there is no way to count with macros, so you can't do the "repeat this n-times" on your own. This is the reason why you can't generate the strings "test 1", "test 2" and so on. It's just not possible. You can, however, create an array of structs with only "test" as string by using the standard array initializer [val; n].
Second, in order to use the array initializer, the type inside the array has to be Copy. But in your case that's not a big problem, since your struct can just derive it.
So let's see, what we can do (playground):
#[derive(Clone, Copy, PartialEq, Debug)]
struct Foo<'a> {
info: &'a str
}
macro_rules! make_foo {
($info:expr; $num:expr) => {
[Foo { info: $info }; $num]
}
}
First, we need to derive a few traits for your struct:
Copy, see above
Clone is required by Copy
PartialEq and Debug are required by assert_eq!()
I think the macro itself is fairly easy to understand: it's just using the array initializer internally.
But how to get exactly the behavior asked in the question?
Don't use a macro and don't use fixed size arrays. A normal function and Vec<T> is probably fine. You could, of course, also write a compiler plugin, but those are unstable right now and it's probably not worth the hassle anyway.

Haxe: Creating a code completion macro for JSON files

I am trying to implement a code completion macro for JSON files by generating field definitions
var classOfChild = Type.getClass(child); // `child` may look like this array: [[1,2,3],[0.1,0.2,0.3]]
fields.push({
"name": childName,
"pos" : _pos,
"kind": childType,
});
I already watched some videos and read some tutorials on this, but there is no information how to get ComplexType from a Type.typeof(object) result.
I have tried code that doesn't work like:
//"kind": childType,
//"kind": childType.toString(),
//"kind": FVar(macro {childType.toString(); }),
//"kind": FVar(macro Array<$v{arrType}>)
but none of them worked (all of them raise some Error or )
Edit 1: here is my json data:
{"floatVar1":0.1, "str":"some string", "nullValueObject":null, "arrayOfInts":[11,20,9], "matrixLikeArray":[[14, 12, 13, 11, 18]], "floatMatrix":[[14.4, 12.3, 13.7, 11.9, 18.0]], "symbolPayouts":[0.05], "objectInObject":{"prop1":"some str", "prop2": "some str2", "prop3":10.17, "prop4":[[1,2,3],[19.3,20.4]]}}
I would like to create Definitions for prop4, ("prop4":[[1,2,3],[19.3,20.4]])
Edit 2: I have already figured out how to create the "kind" for the simple types ("kind": FVar(macro:Dynamic)) and the object (kind : FVar(TAnonymous( jsonFields ))). But how to do that for arrays, arrays of arrays, etc.
Edit 3: code in gist.github.com
When generating code with macros it is easy to attempt to generate something which isn't efficient and you did get side tracked by trying to define explicit types.
Based on your gist, you just need to define a json field and give it the content of your JSON file as the field's value as if you were defining the value as a Haxe literal object.
Your goal is then to generate something you could have written as:
private var json = { prop1:'hello', prop2:42, prop3:[1,2,3] };
The haxe compiler will strongly type this json field.
To achieve that, your macro just need to add one field with an initial value obtained from the JSON file; and likewise, the Haxe compiler will strictly type it.
Creating a variable with a type to be inferred by the compiler is simply FVar(null, valueExpr), which means your entire macro can be reduced to:
var fields = Context.getBuildFields();
var json = Json.parse(src);
fields.push({
name : "json",
pos : Context.currentPos(),
kind : FVar(null, macro $v{json}),
access: [APrivate],
});
return fields;
For a more elaborated version I can point you on the following gist: ResourceGenerator.hx which will generate recursively "inlinable" and dce-friendly objects.
PS: sadly your "prop4":[[1,2,3],[19.3,20.4]] is impossible because it will be seen by the compiler as an Array of incompatible types ([Array<Int>, Array<Float>]).

Generating documentation in macros

I have a couple of macros to reduce boilerplate when defining certain tuple-structs of the form:
macro_rules! new_type (($name:ident, $bytes:expr) => (
pub struct $name(pub [u8; $bytes]);
// some common operations on $name
));
However, I would also like to document these new structs. The best thing would be if I could write my documentation right before my macro invocation.
/// A certain type
new_type!(CertainType, 42);
However, Rust won't generate documentation for CertainType when this happens.
Another (not as flexible) alternative would be to do something like:
macro_rules! new_type (($name:ident, $bytes:expr) => (
/// Some more generic documentation for $name
pub struct $name(pub [u8; $bytes]);
// some common operations on $name
));
However, when doing that the Rust macro system doesn't expand the token $name in the documentation comment. The only alternative left is to write very generic documentation in the macro, but that would lead to my library being a lot worse documented than it could be.
What are your recommendations for handling this? The best solution for me would be to be able to write specific documentation for each macro invocation, but if that's not possible I would be grateful for hints on how to expand tokens in documentation comments.
It is possible to capture doc comments in macro invocations. It is not widely-known, but Rust documentation is actually represented as a special kind of attribute on an item. For example:
/// Some documentation comment
pub fn function() {}
// is equivalent to
#[doc="Some documentation comment"]
pub fn function() {}
And it is possible to capture attributes in macros. There are already several macros which use this ability, the most used probably being bitflags!:
macro_rules! bitflags {
(
$(#[$outer:meta])*
pub struct $BitFlags:ident: $T:ty {
$(
$(#[$inner:ident $($args:tt)*])*
const $Flag:ident = $value:expr;
)+
}
) => { /* ... */ };
// ...
}
Note the $(#[$outer:meta])* and $(#[$inner:meta])* parts of the pattern. These capture all attributes placed before the respective item in the pattern. If you write a doc comment there, it will be converted to the doc attribute and will be passed to rustdoc, as usual.
The following is an example from the quick_error crate which also uses this approach:
quick_error! {
#[derive(Debug)]
pub enum SomeError {
/// IO Error
Io(err: io::Error) {}
/// Arbitrary system error
Sys(errno: nix::Errno) {}
}
}
It does work — here is an example of the structure generated by quick_error macro, and here is its definition.

Specman e compilation error: No such variable 'XXX'

I define a variable my_reg_file in function post_access() (this function is a vr_ad hook for implementing side effects):
//file1.e
extend TIMER_LOAD_0 vr_ad_reg {
post_access(direction : vr_ad_rw_t) is first {
var my_reg_file : TIMER vr_ad_reg_file =
get_parents()[0].as_a(TIMER vr_ad_reg_file);
....
};
};
Then I extend this function in another e file:
//file2.e
extend TIMER_LOAD_0 vr_ad_reg {
post_access(direction : vr_ad_rw_t) is also {
start my_reg_file.some_tcm();
};
};
I get a compilation error:
*** Error: No such variable 'my_reg_file'
Why post_access() does not recognizes the variable my_reg_file? Thank you for your help.
Note: file1.e is imported before file2.e
my_reg_file is a local variable, of that specific method layer, and is not shared with other method layers.
I think the only way to communicate between method layers are:
a. using the result saved variable which can be accessed from any method layer.
b. using a struct member.
Another solution, which seems even better, is to add a separate method to this subtype, e.g. get_my_reg_file(), which will return the desired value, and then call this method where this value is needed, instead of using the local variable.