Listing links in insertion order in rational DOORS - ibm-doors

I have a module A with objects linked from objects in another module B. In a view of A, I have a layout DXL column which lists all those linked B objects:
// DXL generated by DOORS traceability wizard on 02 May 2016.
// Wizard version 2.0, DOORS version 9.2.0.5
pragma runLim, 0
string limitModules[1] = {"40fedbf2697f0e24-00003921"}
void showIter(Object o, string linkModName, int depth, string build, string iter) {
Link l
Object othero
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) {
disp = ""
obuild = probeRichAttr_(othero,"Build", false)
oiter = probeRichAttr_(othero,"Iteration (planned)", false)
string ocat = othero."Category"
if (obuild == build && oiter == iter) {
s = "(B" obuild "." oiter " - " ocat[0] ") " (identifier othero)
disp = disp s
s = probeRichAttr_(othero,"Object Text", false)
disp = disp " " s
displayRich("\\pard " disp)
}
}
}
}
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
Item linkModItem = itemFromID("40fedbf2697f0e24-000039a3")
if (null linkModItem) {
displayRich("\\pard " "<<Link module not found>>")
} else if (type(linkModItem) != "Link") {
displayRich("\\pard " "<<Invalid link module index for this database>>")
} else {
string linkModName = fullName(linkModItem)
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)
}
}
}
//showIter(o, linkModName, depth, "1", "")
//showIter(o, linkModName, depth, "2", "")
showIter(o, linkModName, depth, "3", "3")
}
}
showIn(obj,1)
This script lists the linked objects in numerical order by object ID/key:
B object with ID# 3
B object with ID# 8
B object with ID# 21
B object with ID# 24
Yet in module B, without any sorting active, the objects are visible in insertion order, like this (i.e. according to where I made the insertion):
B object with ID# 24
B object with ID# 8
B object with ID# 21
B object with ID# 3
Is there a way to loop over B objects in insertion order, i.e. in order that they are displayed in B view when no sorting is active?

A "natural" order as you define it, is the order in which the source objects appear in the source module. This does not cover the case where source objects come from different modules, but this is just another problem..
A loop “.. for l in ....” has by definition no order defined, so in case you need one, you have to define your own order. In DXL, this is usually done by Skip lists.
You can create a skip list with the key being of type integer or string and the value being of type Link.
Then for each link, you can somehow calculate the correct order and add an entry where the key represents the order to the Skip list. A later loop „for l in skip“ will process the skip list in the order of the keys.
In your case, you can calculate the key by using a loop over all source objects, with the aid of a temporary skip list, like
int order = 0
Skip skOrderOfObject = create()
Object o
for o in entire (... source module...) do {
order ++
int absno = o."Absolute Number"
put (skOrderOfObject, order, absno)
}
Then to process each source object in your DXL column, you can do a
Skip skMySortedLinks = create()
...
for l in... {
Object oSource = source l
int iOrderOfThisObject
int absnoOfSource = oSource."Absolute Number"
find (skOrderOfObject, absnoOfSource, iOrderOfThisObject);
put (skMySortedLinks, iOrderOfThisObject, l)
}
and finally
Link l
for l in skMySortedLinks do {
... print whatever you want to print...
}

Related

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

Null parameter passed to skip list

I'm getting "null Skip parameter was passed into argument position 1" error for lines 50 and 89 where I want to put the target/source module names into a skip list. I know the loop only executes if there is the out/in link (respectively), so how can it have a null parameter? I also check for the module name to be null, but the check does not make the error box pop up. Both loops execute for a certain number of objects and then stop when it gets to a particular point it doesn't like. Any tips would be appreciated.
/*
Counts the number of non-obsolete requirements in a module and generates a count of number of objects with in/out links, organized by module name. Output is to a CSV file.
*/
pragma runLim, 0 //turn off timeout dialog
filtering off
Module m = current
/***********************
populateBuffer
************************/
void populateBuffer(Buffer &b)
{
Object o = null
Link l
LinkRef lr
ModName_ srcMod
ModName_ tarMod
string targetMod
string sourcMod
int count = 0
int outTotal = 0
int inTotal = 0
int i = 0
int n = 0
Skip OinLinks = createString
Skip OoutLinks = createString
Skip MinLinks = createString
Skip MoutLinks = createString
Skip OutOrphans = create //list of object abs nos which do not have any out links
Skip InOrphans = create //list of object abs nos which do not have any in links
string s = ""
for o in m do
{
if ((o."URB Object Type" "" == "Requirement") && (o."TIS Status" "" != "Obsolete")) //always cast an attribute value as a string with empty quotes
{
for l in o->"*" do //for out links
{
tarMod = target(l)
targetMod = name(tarMod) //puts the target module of the current link into a string
if (null targetMod) {errorBox "FAILURE FINDING TARGET MODULE!"; halt}
print targetMod "\n"
put(OoutLinks, targetMod, count + 1) //puts all of the targetMods into the OoutLinks skip list
n++
}
if (n > 0) //check if this object has outlinks
{
for count in OoutLinks do//for each unique outlink target module of the current object
{
if (find(MoutLinks, targetMod, i)) //if there is already a matching entry
{
delete(MoutLinks, targetMod) //remove the entry for that particular module name
put(MoutLinks, targetMod, i+1) //and re-enter it with count+1 in module level skip list
}
else {put(MoutLinks, targetMod, 1)} //if it is a new entry, add it with count 1
}
}
else //if there are no outlinks,
{
int absno = o."Absolute Number"
put(OutOrphans, absno, 1) //This adds the absno of the current object to
//our orphan list
}
n = 0
for lr in o <-"*" do //for in links
{
sourcMod = name(source lr) //puts the source module of the current link into a string
if (null sourcMod) {errorBox "FAILURE FINDING SOURCE MODULE!"; halt}
print sourcMod "\n"
print "Source Modules \n"
put(OinLinks, sourcMod, count + 1) //puts all of the sourcMods into the OinLinks skip list
n++
}
if (n > 0) //check if this object has inlinks
{
for count in OinLinks do//for each unique inlink target module of the current object
{
if (find(MinLinks, sourcMod, i)) //if there is already a matching entry
{
delete(MinLinks, sourcMod) //remove the entry for that particular module name
put(MinLinks, sourcMod, i+1) //and re-enter it with count+1 in module level skip list
}
else {put(MinLinks, sourcMod, 1)} //if it is a new entry, add it with count 1
}
}
else //if there are no inlinks,
{
int absno = o."Absolute Number"
put(InOrphans, absno, 1) //This adds the absno of the current object to
//our orphan list
}
delete(OinLinks) //reset the OinLinks list so we can start fresh for the next object
delete(OoutLinks) //reset the OoutLinks list so we can start fresh for the next object
n = 0
}
else continue
}
}
/************************************
MAIN
*************************************/
string fName = "C:/Temp/LinkedObjectsInventory_Jan8.csv"
Stream outfile = write(fName)
Buffer b = create
populateBuffer(b)
outfile << b
close(outfile)
delete(b)
// notify the user that the script is complete
ack "Inventory Complete."
This is a pretty straightforward issue-
The change I would make- replace this:
delete(OinLinks) //reset the OinLinks list so we can start fresh for the next object
delete(OoutLinks) //reset the OoutLinks list so we can start fresh for the next object
with this:
for count in OinLinks do //reset the OinLinks list so we can start fresh for the next object
{
delete ( OinLinks , ( string key OinLinks ) )
}
for count in OoutLinks do //reset the OoutLinks list so we can start fresh for the next object
{
delete ( OoutLinks , ( string key OoutLinks ) )
}
As part of your for each object loop, you were deleting the entire skip list rather than emptying it. This meant that on a subsequent loop, the program could not find the Skip list and threw an error. It's good to reuse skips rather than re-allocate them each time, but you have to empty the contents rather than call delete on the skip handle.
Good luck, and let me know if you have other issues!

Doors DXL filter ,

I have the following snip of dxl code,
I would like to copy the object ID with the filter F3 is on. :
I dont know what I am doing wrong it gives me (ID) of all the object.
string Id
int x=0;
int y=0;
Id = o."SourceID"
Filter f0 = hasNoLinks(linkFilterIncoming, "*")
Filter f1=attribute "_TraceTo" == "System"
Filter f2 = attribute "Object Type" == "requirement"
Filter f3 = f1&&f2&&f0
addFilter(m,f3,x,y)
print x ":\t" fullName(module(m)) "\n"
wOutKLHUntraced << Id "\t" fullName(module(m)) "\n"
First, you need to add the statement filtering on after adding the filter, so that the filter is applied. Then the filtered objects will be the only ones visible.
Then, you set "Id" way too early in the script. At line 4, "o" is set to
some object, I don't know which one, but certainly not the result of
your filter. Instead, after the statement filtering on, add statements
Object o = first m // the first object that is now visible
Id = o."SourceID"
My Script is running good, but gives different results : as I am running this script in a for loop for around 30 module :
Am I am setting somewhere wrong filters ?
Stream TbdUntraced;
string s
string d
Object o
string trac
int numReqs = 0;
string IdNum
string untraced
int x=0;
int y=0;
int a =0;
for o in m do
{
ensureInLinkedModulesLoaded(o,S_SATISFIES );
s = o."Object Type"
string Id
string Topic
Topic = o."_Topic"
numReqs++;
Filter f0 = hasNoLinks(linkFilterIncoming, "*")
Filter f1 = contains(attribute "_TraceTo", "TBD", false)
Filter f2 = attribute "Object Type" == "requirement"
Filter f3 = attribute "MMS5-Autoliv_Supplier_Status" == "agreed"
Filter f4 = attribute "MMS5-Autoliv_Supplier_Status" == "partly agreed"
Filter f7 = f0&&f2&&(f3||f4)&&f1
addFilter(m,f7,x,y)
filtering on
d = o."MMS5-Autoliv_OEM_Status"
Id = o."SourceID"
Topic = o."_Topic"
print x ":\t" name(module(m)) "\n"
TbdUntraced << Id "\t" Topic "\t"name(module(m)) "\n"
}

Show DXL columns from other modules

I'm working in a formal module with one type of in-links. These links (we call it as Type X links) are made in 4 depth level from 4 different formal modules. For example I'm working in module A, that have in-links from module B, that have in-links from module C, that have in-links from module D.
I have a view that shows in different columns each in-link level: Column 1: Depth 1 links (A-B), Column 2: Depth 2 links (B-C), Column 3: Depth 3 links (C-D).
Each column is generated by an script like this:
pragma runLim, 0
int lines[4] = {0, 0, 0, 0}
void adjustLines(int depth, showAtDepth) {
int count
for (count = 0; count < 4; count++) {
while (lines[depth-1] < lines[count]) {
if (depth == showAtDepth) displayRich("\\pard " " ")
lines[depth-1]++
}
}
}
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 = "../links/TYPE X"
for lr in all(o<-linkModName) do {
otherMod = module (sourceVersion lr)
if (!null otherMod) {
if ((!isDeleted otherMod) && (null data(sourceVersion lr))) {
load((sourceVersion lr),false)
}
}
}
for l in all(o<-linkModName) do {
otherVersion = sourceVersion l
otherMod = module(otherVersion)
if (null otherMod || isDeleted otherMod) continue
othero = source l
if (null othero) {
load(otherVersion,false)
}
othero = source l
if (null othero) continue
if (isDeleted othero) continue
int oldLines = lines[depth-1]
adjustLines(depth, 1)
bool kick = (doneOne) && (lines[depth-1] == oldLines)
if (kick) {
lines[depth-1]++
if (depth == 1) displayRich("\\pard " " ")
}
if (depth < 4) {
showIn(othero, depth+1)
}
doneOne = true
if (depth == 1) {
s = name(otherMod)
if (isBaseline(otherVersion)) {
s = s " [" versionString(otherVersion) "]"
}
s = "{\\b " s " : }"
s = s " " probeRichAttr_(othero,"Object Heading", false)
s = s " " probeRichAttr_(othero,"Object Text", false)
displayRich s
}
lines[depth-1] += 3
}
}
showIn(obj,1)
However now, I have to add a new column that contains other type of link (Type Y) defined between module C and other new module do not linked directly with my module (A). Fortunately, I have these relationship in a column at module C (as a layout dxl).
How can I show in my module (A) that column saved in a view at module (C) to be saved in my current view?
Thank you in advance for your cooperation and your help
Follow the Type X links to module C, and then follow Type Y links.
Change:
string linkModName = "../links/TYPE X"
To:
string linkModName = (depth<3) ? "../links/TYPE X" : "../links/TYPE Y"
You may need a different number as I'm not sure of you structure.

DOORS DXL for changing Versioned Links to specific target baseline

I would like to be able to change the Baseline attribute for all outlinks from a source module. Does anyone know of some DXL code that could be used to do this?
There must be an easier way rather than manually deleting previous outlinks (i.e. ModuleVersion BL [1.20] and recreating outlinks to a specific new baseline (i.e. ModuleVersion BL [1.21]).
for outLink in all (Object srcObject) -> (string linkModName) do {
...
targetVersion(outLink) ...
}
Thanks for any help.
Here is the dxl way to do it:
Link ol
Object o
Object othero
Module m = current
string LinkModName = "FULLPATHTOLINKMODULE"
Module tMod
ModName_ tModName
ModuleVersion mv
Baseline b
int tAbs
// Current Version of the Links
string cVersion = "1.20"
// Target Major, Minor and Suffix
int tMajor = 1
int tMinor = 21
string tSuffix = ""
for o in m do
{
for ol in all(o -> LinkModName) do
{
mv = targetVersion(ol)
tModName = target(ol)
tMod = read(fullName(tModName),false)
if(isBaseline(mv))
{
if(versionString(mv) "" == cVersion)
{
if(!isBaseline(tMod))
{
b = baseline(tMajor,tMinor,tSuffix)
if(baselineExists(tMod,b))
{
tMod = load(tMod, b, true)
} else {
ack "Baseline [" tMajor "." tMinor " " tSuffix "] was not found"
halt
}
}
tAbs = targetAbsNo(ol)
othero = object(tAbs,tMod)
if(!null othero)
{
o -> LinkModName -> othero
delete ol
}
}
}
}
}
flushDeletions()
save m
Don't forget to insert the path to your link module and update the baseline information for the current and target if necessary.
You can omit the delete ol and flushDeletions() if you decide not to remove the old links.

Resources