DXL open a module - ibm-doors

Basically I would need a script(or function) that would look after a module (using it's name as a parameter),within a database and not projects, and return the module as it is for further operations on it.
I am using DOORS 9.3

Something like this should get you started:
Item i
Folder f = folder("/")
Folder f2
void drill_items(Folder f) {
for i in f do {
if(type(i) "" == "Formal")
\\ Do some logic here to check if its the module you are looking for.
\\ If you find it, break out and return the Module handle.
else if((type(i) "" == "Project") || (type(i) "" == "Folder")) {
f2 = folder(fullName(i) "")
drill_items(f2)
}
}
}
drill_items(f)
You could write something using a regular expression to compare some input to the module name to find the one you are looking for.
-Steve

Related

Implement heredocs with trim indent using PEG.js

I working on a language similar to ruby called gaiman and I'm using PEG.js to generate the parser.
Do you know if there is a way to implement heredocs with proper indentation?
xxx = <<<END
hello
world
END
the output should be:
"hello
world"
I need this because this code doesn't look very nice:
def foo(arg) {
if arg == "here" then
return <<<END
xxx
xxx
END
end
end
this is a function where the user wants to return:
"xxx
xxx"
I would prefer the code to look like this:
def foo(arg) {
if arg == "here" then
return <<<END
xxx
xxx
END
end
end
If I trim all the lines user will not be able to use a string with leading spaces when he wants. Does anyone know if PEG.js allows this?
I don't have any code yet for heredocs, just want to be sure if something that I want is possible.
EDIT:
So I've tried to implement heredocs and the problem is that PEG doesn't allow back-references.
heredoc = "<<<" marker:[\w]+ "\n" text:[\s\S]+ marker {
return text.join('');
}
It says that the marker is not defined. As for trimming I think I can use location() function
I don't think that's a reasonable expectation for a parser generator; few if any would be equal to the challenge.
For a start, recognising the here-string syntax is inherently context-sensitive, since the end-delimiter must be a precise copy of the delimiter provided after the <<< token. So you would need a custom lexical analyser, and that means that you need a parser generator which allows you to use a custom lexical analyser. (So a parser generator which assumes you want a scannerless parser might not be the optimal choice.)
Recognising the end of the here-string token shouldn't be too difficult, although you can't do it with a single regular expression. My approach would be to use a custom scanning function which breaks the here-string into a series of lines, concatenating them as it goes until it reaches a line containing only the end-delimiter.
Once you've recognised the text of the literal, all you need to normalise the spaces in the way you want is the column number at which the <<< starts. With that, you can trim each line in the string literal. So you only need a lexical scanner which accurately reports token position. Trimming wouldn't normally be done inside the generated lexical scanner; rather, it would be the associated semantic action. (Equally, it could be a semantic action in the grammar. But it's always going to be code that you write.)
When you trim the literal, you'll need to deal with the cases in which it is impossible, because the user has not respected the indentation requirement. And you'll need to do something with tab characters; getting those right probably means that you'll want a lexical scanner which computes visible column positions rather than character offsets.
I don't know if peg.js corresponds with those requirements, since I don't use it. (I did look at the documentation, and failed to see any indication as to how you might incorporate a custom scanner function. But that doesn't mean there isn't a way to do it.) I hope that the discussion above at least lets you check the detailed documentation for the parser generator you want to use, and otherwise find a different parser generator which will work for you in this use case.
Here is the implementation of heredocs in Peggy successor to PEG.js that is not maintained anymore. This code was based on the GitHub issue.
heredoc = "<<<" begin:marker "\n" text:($any_char+ "\n")+ _ end:marker (
&{ return begin === end; }
/ '' { error(`Expected matched marker "${begin}", but marker "${end}" was found`); }
) {
const loc = location();
const min = loc.start.column - 1;
const re = new RegExp(`\\s{${min}}`);
return text.map(line => {
return line[0].replace(re, '');
}).join('\n');
}
any_char = (!"\n" .)
marker_char = (!" " !"\n" .)
marker "Marker" = $marker_char+
_ "whitespace"
= [ \t\n\r]* { return []; }
EDIT: above didn't work with another piece of code after heredoc, here is better grammar:
{ let heredoc_begin = null; }
heredoc = "<<<" beginMarker "\n" text:content endMarker {
const loc = location();
const min = loc.start.column - 1;
const re = new RegExp(`^\\s{${min}}`, 'mg');
return {
type: 'Literal',
value: text.replace(re, '')
};
}
__ = (!"\n" !" " .)
marker 'Marker' = $__+
beginMarker = m:marker { heredoc_begin = m; }
endMarker = "\n" " "* end:marker &{ return heredoc_begin === end; }
content = $(!endMarker .)*

Determining context at a position in file using ANTLR4

I'm trying to write a Language Extension for VS Code in JavaScript and I seem to be missing something.
I have a Lexer.g4 and Parser.g4 for my language and can generate a tree using them.
My issue is that the VS Code API gives me a document and a position in that document (line #, character #). From any of the examples I've looked at for ANTLR4 I can't seem to find any functions generated that take a position in the file and give back the nodes of a tree at that position.
I want to know, for example that the cursor is placed on the name of a function.
Am I supposed to be walking the entire tree and checking the position of tokens to see if they enclose the position I'm in in the editor? Or maybe I'm not using the right tool for the job? I feel like I'm probably missing something more fundamental.
Yes, you have to walk the parse tree to find the context at a given position. This is a pretty simple task and you can see it in action in my ANLTR4 exension for vscode. There are multiple functions returning something useful for a given position. For instance this one:
/**
* Returns the parse tree which covers the given position or undefined if none could be found.
*/
function parseTreeFromPosition(root: ParseTree, column: number, row: number): ParseTree | undefined {
// Does the root node actually contain the position? If not we don't need to look further.
if (root instanceof TerminalNode) {
let terminal = (root as TerminalNode);
let token = terminal.symbol;
if (token.line != row)
return undefined;
let tokenStop = token.charPositionInLine + (token.stopIndex - token.startIndex + 1);
if (token.charPositionInLine <= column && tokenStop >= column) {
return terminal;
}
return undefined;
} else {
let context = (root as ParserRuleContext);
if (!context.start || !context.stop) { // Invalid tree?
return undefined;
}
if (context.start.line > row || (context.start.line == row && column < context.start.charPositionInLine)) {
return undefined;
}
let tokenStop = context.stop.charPositionInLine + (context.stop.stopIndex - context.stop.startIndex + 1);
if (context.stop.line < row || (context.stop.line == row && tokenStop < column)) {
return undefined;
}
if (context.children) {
for (let child of context.children) {
let result = parseTreeFromPosition(child, column, row);
if (result) {
return result;
}
}
}
return context;
}
}

DOORS Layout DXL is reporting each link twice

I'm using the Analysis Wizard to create a LayoutDXL column which should list attributes (e.g. AbsoluteNumber) for each existing In-link in my current module. In one particular DOORS module, the resulting DXL code displays each of these attributes twice. This doesn't happen in other modules.
I did notice that the offending module doesn't have a defined set of LinkModules (as seen in File/ModuleProperties). Could that be causing some sort of loopback?
Update:
I've discovered that somehow the DXL code "thinks" there are two versions of a defined LinkModule, i.e. "Current" and "Baseline X" . These each link to different baseline numbers in the target DOORS module. I don't know how to fix that.
For reference, here's the DXL code generated with the Wizard. This is DOORS 9.6.1.11
// DXL generated by DOORS traceability wizard on 12 February 2019.
// Wizard version 2.0, DOORS version 9.6.1.11
pragma runLim, 0
string limitModules[1] = {"[serial number redacted]"}
void showIn(Object o, int depth) {
Link l
LinkRef lr
ModName_ otherMod = null
Module linkMod = null
ModuleVersion otherVersion = null
Object othero
string disp = null
string s = null
string plain, plainDisp
int plainTextLen
int count
bool doneOne = false
string linkModName = "*"
for lr in all(o<-linkModName) do {
otherMod = module (sourceVersion lr)
if (!null otherMod) {
if ((!isDeleted otherMod) && (null data(sourceVersion lr))) {
if (!equal(getItem otherMod, (itemFromID limitModules[depth-1]))) continue
load((sourceVersion lr),false)
}
}
}
for l in all(o<-linkModName) do {
otherVersion = sourceVersion l
otherMod = module(otherVersion)
if (null otherMod || isDeleted otherMod) continue
if (!equal(getItem otherMod, (itemFromID limitModules[depth-1]))) continue
othero = source l
if (null othero) {
load(otherVersion,false)
}
othero = source l
if (null othero) continue
if (isDeleted othero) continue
doneOne = true
if (depth == 1) {
s = probeRichAttr_(othero,"Absolute Number", false)
if (s == "")
displayRich("\\pard " " ")
else
displayRich("\\pard " s)
s = probeRichAttr_(othero,"Object Heading", false)
if (s == "")
displayRich("\\pard " " ")
else
displayRich("\\pard " s)
}
}
}
showIn(obj,1)
I've seen the situation where objects DID have two links between them, this is possible with different link modules (Object 1 of Module A SATISFIES Object 2 of Module B and Object 1 of Module A REFINES Object 2 of Module B). While there may be reasons for such a situation, most often this is caused by a "link move" script that was not used correctly.
You should augment your code by displaying the name of the link module as well (variable linkModName). Perhaps this shows the reason for your observation

checking an object in a nested link via dxl

I have the following situation.
I want to count in Module 1, how many objects are having links in links from Module 3.
example:
Module 1 Obj1 <- Module 2 Obj1 <- Module 3.Obj1
Module 1 Obj2 <- Module 2 Obj1 <- Module 3.Obj1
Module 1 Obj3 <- Module 2 Obj1 <- Module 3.Obj1
Module 1 Obj4 <- Module 2 Obj1
Module 1 Obj5 <- Module 2 Obj1
The count should return 3, in the above case.
Is it possible via DXL to follow a link, and then follow another link?
(not using the Wizard or DXL attributes)
Most important for me: knowing if somebody else did this and it's possible to do.
Please try the following DXL from within the module that has the incoming links. Before running the code:
make sure that you open the 'Edit DXL' window from the relevant module
set the string values assigned to global constant STR_LINK_MOD_FULLNAME (line 17) to the full pathname of the link module whose links you are interested in
set the string values assigned to global constant STR_SRC_MOD_FULLNAME (line 18) to the full pathname of the source formal module (Module 3, in your example) whose links you are interested in
You shouldn't need to change anything else to make it work.
N.B. I have not considered the implications of analysing links in all link modules by using the string "*" in place of a specific link module name in line 17 (see point 2, above).
I also haven't gone out of my way to explain the code, though I have tried to be nice and tidy up after myself where DOORS and DXL require it. Please feel free to reply with any questions on what I have done.
Kind regards,
Richard
//<CheckObjectInNestedLink.dxl>
/*
*/
///////////////
// Sanity check
if (null (current Module))
{
print "ERROR: this script must be run from a Formal Module."
}
///////////////////
// Global Constants
const string STR_LINK_MOD_FULLNAME = "/New Family Car Project/Admin/Satisfies" // the fullName of a single link module - results of using "*" have not been considered/tested
const string STR_SRC_MOD_FULLNAME = "/New Family Car Project/Architecture/Architectural Design" // The fullName of the desired source Formal Module
///////////////////
// Global Variables
Module modSource = null
Object objTarget = null
Object objSource = null
Link lkIn = null
Skip skLinkedMods = create()
Skip skObjsWithDesiredSource = create()
int intNoOfLinked = 0
//////////////////////
// Auxiliary Functions
void closeSourceMods ()
{
Module srcMod
for srcMod in skLinkedMods do
{
close(srcMod)
}
}
void openSourceMods (Object objWithLinks)
{
ModName_ srcModRef
Module srcMod
for srcModRef in (objWithLinks <- STR_LINK_MOD_FULLNAME) do
{
srcMod = read(fullName(srcModRef), false)
put(skLinkedMods, srcMod, srcMod)
}
}
void recurseFollowInLinks (Object objWithLinks)
{
openSourceMods(objWithLinks)
for lkIn in objWithLinks <- STR_LINK_MOD_FULLNAME do
{
openSourceMods(objWithLinks)
objSource = source(lkIn)
string strSrcModName = fullName(module(objSource))
if (strSrcModName == STR_SRC_MOD_FULLNAME)
{
bool blNewEntry = put(skObjsWithDesiredSource, objTarget, objTarget)
if (blNewEntry)
{
intNoOfLinked++
}
//print "put(skObjsWithDesiredSource, " identifier(objTarget) ", " identifier(objTarget) ")\n"
}
recurseFollowInLinks(objSource)
}
}
void checkObjectInNestedLink (Module modThis, string strSourceModuleFullname, string strLinkModuleFullName)
{
intNoOfLinked = 0
for objTarget in modThis do
{
recurseFollowInLinks(objTarget)
}
print "The following " intNoOfLinked " objects have direct or indirect links of type " STR_LINK_MOD_FULLNAME " from formal module " STR_SRC_MOD_FULLNAME ":\n"
for objTarget in skObjsWithDesiredSource do
{
print identifier(objTarget)
print "\n"
}
}
///////////////
// Main Program
checkObjectInNestedLink ((current Module), STR_SRC_MOD_FULLNAME, STR_LINK_MOD_FULLNAME)
closeSourceMods()
delete(skLinkedMods)
delete(skObjsWithDesiredSource)

Grails config file closure definition

I'm writing a config file for grails app where I want to define redirect patterns.
I've written a config script RedirectMappingsConfig.groovy:
import java.util.regex.Pattern
def c = {pattern, goto, path ->
if (pattern instanceof Pattern && pattern.matcher(path).matches()) {
return goto
}
return false
}
def redirectFromTo = [
c.curry(Pattern.compile('/si/reference.*'), '/enterprise-solutions/references-and-partners#references'),
c.curry(Pattern.compile('/si/kontakt.*'), '/contact-us'),
c.curry(Pattern.compile('/si/zaposlitve.*'), '/careers'),
c.curry(Pattern.compile('/aa'), '/')
]
This list will be read in a filter which will perform redirect if some pattern matches request uri.
Problem: application does not compile, the error is:
Compilation error: startup failed:
RedirectMappingsConfig.groovy: 3: unexpected token: pattern # line 3, column 10.
def c = {pattern, goto, path ->
^
Any idea what is wrong with the syntax?
I'm using grails 2.1.1.
goto is a reserved word in Groovy... Change your closure to:
def c = {pattern, addr, path ->
if (pattern instanceof Pattern && pattern.matcher(path).matches()) {
return addr
}
return false
}
And this error should go away :-)

Resources