Specman e: Is there a way to print unit instance name? - specman

I've built a generic agent that will be instantiated several times in the environment:
unit agent_u {
monitor : monitor_u is instance;
};
The monitor prints some messages, e.g.:
unit monitor_u {
run() is also {
message(LOW, "Hello monitor!");
};
};
I would like to add to the monitor's messages which agent instance has printed them. For example, for environment:
extend sys {
first_agent : agent_u is instance;
second_agent : agent_u is instance;
};
the desirable output will be something like that:
first_agent: Hello monitor!
second_agent: Hello monitor!
I could not find anything related to instance name in the reflection API... Is there some way to print an instance name in e?
Thank you for your help

printing with message() will already include the instance pointer, in your case something like:
[0] agent_u-#1: Hello monitor!
[0] agent_u-#2: Hello monitor!
you can distinguish by these #NUM.
or include "me.e_path()" in your message, which will give the full instance path:
message(LOW, me.e_path(), ": Hello monitor!");
[0] agent_u-#1: sys.first_agent.monitor: Hello monitor!
[0] agent_u-#2: sys.second_agent.monitor: Hello monitor!

Not sure what exactly you refer to by "the instance name", but there are several points to be aware of.
There is the predefined e_path() method of any_unit.
There is a unique identifier for struct and unit instances, consisting of the type name and a unique number, which is returned by to_string() method. This unique identifier is already printed as part of a message.
Moreover, you can use the predefined hook method create_formatted_message(), preferably together with defining your own new message_format, to customize how messages are printed. For example, you might append the result of e_path() to the formatted message string, if you wish it to automatically appear in all messages.
You can also use the short_name() hook to provide your own symbolic names to units, and those will appear in messages instead of the result of to_string().
In principle, you can also override to_string() itself, but that would have more effects than just messages printout.

Related

SNMPTraps: pysnmp and "disableAuthorization"

I have written an SNMP trap receiver but currently I have to hardcode all the SNMPv2 community strings to be able to receive the traps.
How do I emulate the 'disableAuthorization' functionality from snmptrapd in pysnmp?
I have tried to not set the community string: config.addV1System(snmpEngine, 'my-area') but this errors about a missing param. I have also tried an empty string: config.addV1System(snmpEngine, 'my-area', '') but this stops all traps being processed.
What is the best way to allow receiving all traps through pysnmp regardless of the community string they were sent with? I haven't found anything in the pysnmp docs that could help me
I had made progress on setting up an observer for V1/2 (V3 to be added later) that picked up on notifications with an unknown community string and then called addV1System on the fly to dynamically add it in, like so:
When setting up the transportDispatcher:
snmpEngine.observer.registerObserver(_handle_unauthenticated_snmptrap,
"rfc2576.prepareDataElements:sm-failure", "rfc3412.prepareDataElements:sm-failure")
And then:
def _handle_unauthenticated_snmptrap(snmpEngine, execpoint, variables, cbCtx):
if variables["securityLevel"] in [ 1, 2 ] and variables["statusInformation"]["errorIndication"] == errind.unknownCommunityName:
new_comm_string = "%s" % variables["statusInformation"].get("communityName", "")
config.addV1System(my_snmpEngine, 'my-area', new_comm_string)
return
else:
msg = "%s" % variables["statusInformation"]
print(f"Trap: { msg }")
However, this will always throw away the first trap received while adding any new community string (and then there is the problem whereby when the daemon is restarted the updated list of community strings is lost).
In looking to improve this I then found hidden away in the docs this little gem:
https://pysnmp.readthedocs.io/en/latest/examples/v3arch/asyncore/manager/ntfrcv/advanced-topics.html#serve-snmp-community-names-defined-by-regexp
This example receives a notification and rewrites the community string into 'public' so all traps will be correctly received.
In essence, when setting up the transportDispatcher:
my_snmpEngine.observer.registerObserver(_trap_observer,
'rfc2576.processIncomingMsg:writable', cbCtx='public')
And then:
def _trap_observer(snmpEngine, execpoint, variables, community_string):
variables['communityName'] = variables['communityName'].clone(community_string)

VSCode Extension: Get outline of function for custom outliner

I'm trying to create a custom outliner for VSCode (currently only for python), but I don't find measures to get the information I needed.
I like to get information in this manner this:
Array:
[0]
label: "foo"
type: "Function"
parameters: [...]
Range: [...]
innerDefinitions: [0]
[1]
label: "myclass"
type: "Class"
base_class: ""
Range: [...]
innerDefinitions:
[0]:
[...]
[1]:
[...]
Currently I try to get outline information via vscode.commands.executeCommand( 'vscode.XXX'
What I've tried:
Here is what commands I've tried and what result I received.
vscode.executeImplementationProvider
half usable: range of functionname. Other information is missing
vscode.executeHoverProvider
half usable: string of function head (including def keyword)
vscode.executeDefinitionProvider
half usable: range of complete function. Individual information must be "parsed out"
vscode.executeTypeDefinitionProvider
Never provided any result
vscode.executeDeclarationProvider
Never provided any result
vscode.executeDocumentSymbolProvider
Goes in a good direction. However
(1) Does only work on the whole document (not single function)
(2) Does only return first-level entities (i.e. class methods are not included in result)
Is there any API call I've overseen?
I wonder how the built-in outliner works, as it contains all-level information.
You need to use vscode.commands.executeCommand<vscode.Location[]>("vscode.executeDocumentSymbolProvider", uri, position)
This will give you the full outline of one file. There is no way to receive a partial outline.
Note: innerDefinitions are called children here.
Regarding the detail of the outline:
How detailed (and correct) an outline is going to be, depends on the implementation of the provider. Also, provider's information is no necessarily consistent among languages. This is very important to keep in mind!
At the moment (2021/03), the standard SymbolProvider for...
... Python will have a child for each parameter and local variable of a function. They will not be distinguishable
... C++ will contain no children for parameters. But it will have the parameter types in its name. (e.g. name of void foo(string p) will be foo(string): void.
As you can see, both act differently with their own quirks.
You could create and register a DocumentSymbolProvider yourself, that would return a level of detail you need (see VSCode Providers)
Also see: https://stackoverflow.com/a/66486297/6702598

kdb/q - geting an expression by location to its containing source code string?

I'm playing around with Q's new .Q.trp, and the debug object which you're given in case of an error.
From what I see, the debug object contains a string representation of the source code where the error occured, as well as the offset in that string where the error was triggered.
For example,
{
something: 123;
x: 123; ThisThrowsAnError[456;789]; y: 123;
}[]
when executing above code, the debug object would contain this code in its entirity, as well as the offset pointing to (the beginning of) ThisThrowsAnError[].
My question is - based on this information, how can I extract the entire statement that cuased the error?
For example, in above example, I'd like to extract "ThisThorwsAnError[456;789]".
Things I've thought of so far...
Extract string from the offset, until the end of line. Doesn't work though, as there might be other statements in the same line (e.g. the "y: 123" above)
Parse the source code (literally, with "parse"). But then what..? The output could be anything (e.g. a lambda or a statement list), and then whatever it is still needs to be mapped back to the source locations somehow
Appreciate any ideas! Thanks

Get "name" for object, corresponding to package name and object name

Given the object:
package com.foo.bar
object Sample {
val LOG = org.slf4j.LoggerFactory.getLogger(???)
....
}
what statement/function/whatever I put into getLogger statement in order to get "com.foo.bar.Sample" ?
Basically, it's just a matter of code style, for the moment I configured IntelliJ to generate LOG statements with strings, evaluated from template like "packagename.classname". But may be there's some better way?
Thanks.
In this case you could use getClass().getName().

MIDL marshaling array of structures using size_is in unmanaged c++

I’m trying to retrieve an array of structures through a COM interface. It works when the number of structures is 1. When the number of structures is greater than 1, only the first structure is marshaled correctly. The remaining structures in the array have garbage data.
My interface looks like this:
typedef struct tagINTOBJINTERFACE
{
long lObjectId;
IMyObject* pObj;
} INTOBJINTERFACE;
[
object,
uuid(<removed>),
dual,
nonextensible,
helpstring("Interface"),
pointer_default(unique)
]
interface IMyInterface : IUnknown {
HRESULT CreateObjects(
[in] VARIANT* pvDataStream,
[out]long* Count,
[out,size_is(,*Count)] INTOBJINTERFACE** ppStruct
);
};
I allocate the structure memory like this:
long lCountInterfaces = listInterfaces.GetCount();
long lMemSize = lCountInterfaces * sizeof(INTOBJINTERFACE);
INTOBJINTERFACE* pstruct = (INTOBJINTERFACE*) CoTaskMemAlloc( lMemSize );
And then fill in the members of each structure in the array. I can see in the debugger that all members of all array elements are properly assigned.
After filling in the structures, I assign “*ppStruct = pstruct” to pass the array out.
I can also see that the out parameter “*Count” is properly set to the correct number of elements.
Why doesn’t this work?
Reason:
Your application uses the universal marshaller from windows for mashalling.
The universal marshaller reads the meta data from your typelib (*.tlb).
The generated typelib doesn't support size_is.
Todo:
You should use the Proxy/Stub dll generated by Visual Studio (...PS project).
- Build the Proxy/Stub dll
- call "regsvr32 "
- remove the "TypeLib = s '{?????-...-????}'" entry from your servers "*.rgs"
file
In addition to Joerg's answer that using size_is is not possible, here is what's possible: SAFEARRAY.
Keywords: Safearray of UDT
Explanation and examples are here
Short summary:
Define structure with a GUID.
Create object of type IRecordInfo that describes your structure using the type library.
Use SafeArrayCreateEx to create SAFEARRAY of type VT_RECORD.
Fill it with data.
Retrieve on the other side.