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
I am trying to write a simple DXL that checks for out links. More specifically, I want to look through every requirement in a formal module and return the number of items missing an out link:
Module m = current
Object o = null
string objType = ""
Link outLink
int noOutLinkCount = 0
for o in m do {
objType = o."Object Type"
for outLink in o -> "*" do {
if objType == "Req" or objType = "Obj" and outLink == null then noOutLinkCount++
}
}
print "No Out Link Count = " noOutLinkCount""
For the life of me, I cannot figure out how to do this. The condition
outLink == null
does not seem to work.
Note: Checking to make sure the object is of type "Req" (Requirement) or "Obj" (Objective Requirement) is necessary as I do not care about missing links on Headers, images, text objects, etc.
This loop:
for outLink in o -> "*" do {
}
Will execute for each outlink. It will not execute at all if there are 0 outlinks.
I would structure the code like so:
Module m = current
Object o = null
string objType = ""
Link outLink
int noOutLinkCount = 0
for o in m do {
objType = o."Object Type" ""
// Check if the type is right
if ( ( objType == "Req" ) || ( objType == "Obj" ) ) {
// Check for any outlinks at all
bool no_outlink_flag = true
for outLink in o -> "*" do {
// If this executes, at least 1 outlink- flag and break
no_outlink_flag = false
break
}
// If we didn't flag any outlinks, increment
if ( no_outlink_flag ) {
noOutLinkCount++
}
}
}
print "No Out Link Count = " noOutLinkCount""
That should work. Let me know if it does!
The background to the question is, that I would like to create software change requests from Doors requirement changes.
For this I have to get the differences of requirements between two user selectable baselines of a module in a human readable format.
In the GUI I use the "Baseline Compare" function.
How can I access these results from a script (inside or outside of Doors) in a structured format?
A good starting point might the Doors DXL library Tools -> DXL Library -> baseline comparator example, but it needs heavy modifications for your overall use-case I guess. Take a look.
Found a modified version of the baseline compare script at this forum . I haven't tried it yet, but here's the code, which does use a GUI but you should be able to redirect the input & output pretty easily:
// Your Company Baseline Compare with Attributes
/*
Date Posted: 16-Jan-2008 00:03
Posted By: Juergen Albrecht
*/
/*
// (Your Company Baseline Compare) *
//---------------------------------------------------------------------------*
// *
// Project: Your Company Ottobrunn *
// *
//---------------------------------------------------------------------------*
// Module: all modules for baseline compare *
//---------------------------------------------------------------------------*
// Description: ... *
// *
// Functions: compare any two baselines of the current module *
// (or a baseline against the current version). *
// Sets a filter on objects which differ with request *
// to Object Heading, Object Text, Object Type and .... *
// *
// *
// Copyright (C) Your Company Your Town 2005-2007 Confidential. All rights reserved. *
//---------------------------------------------------------------------------*
// *
// $Header: /doors/lib/dxl/addins/user/BaselineCompare.dxl Ver. 1.0 15.03.06 18:00 UID-USER $
// *
//---------------------------------------------------------------------------*
// $History: BaselineCompare.dxl $
//
//********************************* Version 1.0 ****************************
// User: Date: Time: *
// Jürgen Albrecht (uid-al28423) 15.01.08 18:00
// Created in $/doors/lib/dxl/addins/user/BaselineCompare.dxl
//---------------------------------------------------------------------------*
// *
// *
// *
//---------------------------------------------------------------------------*
*/
pragma runLim, 0
////////////////////////////////////////////////////// constants for Attributes
const string DUMMY_LIST[] = {}
const string strAffectsArr[] = {"Ch.Bars", "Ch.Date", "History"}
const string strCharacterArr[] = {"System ", "Hidden ", "Customised"}
const string strValidityArr[] = {"Module ", "Object"}
const string strPropertyArr[] = {"Inherited", "Multi value"}
////////////////////////////////////////////////////// variables for Attributes
DB dbBLCompare = null
DBE dbeAttrDefNameList = null
DBE dbeAttrCharacter = null
DBE dbeAttrAffects = null
DBE dbeAttrValidity = null
DBE dbeAttrProperty = null
DBE dbeAttrType = null
DBE dbeDefaultValue = null
DBE dbeAttrTypeList = null
DBE dbeAttrTypeSelect = null
////////////////////////////////////////////////////// functions for Attributes
int chopInsert2(DBE inlist, string s)
{ int no_inlist = noElems inlist
int low = 0
int high = no_inlist-1
int hw = 0
string c
if (no_inlist == 0)
{ insert(inlist,0,s)
setCheck(inlist,0,false)
return 0
}
while (high-low > 1)
{ hw = low + ((high-low) / 2)
c = get(inlist,hw)
if (s < c)
high = hw
else
low = hw
}
c = get(inlist,high)
if (c < s)
{ insert(inlist,high+1,s)
setCheck(inlist,high+1,false)
return high + 1
}
c = get(inlist,low)
if (c > s)
{ insert(inlist,low,s)
setCheck(inlist,low,false)
return low
}
insert(inlist,low+1,s)
setCheck(inlist,low+1,false)
return low+1
} // chopInsert2
void populateLstAttrDef(bool bIncludeSystemAttr)
{ AttrDef ad
for ad in current Module do
{ if (ad.module)
continue
if (!bIncludeSystemAttr)
{ if (ad.system || ad.hidden)
continue
}
chopInsert2(dbeAttrDefNameList, ad.name "")
}
set(dbeAttrDefNameList, 0, true)
} // populateLstAttrDef
void doNothing(DBE dbeKlick, int iKlick)
{
} // doNothing
void cbSystemSelect(DBE dbeKlick)
{ bool bSelect = get(dbeAttrTypeSelect)
empty (dbeAttrDefNameList)
populateLstAttrDef (bSelect)
} // cbSystemSelect
void doSetAttrTypes(void)
{
AttrDef ad = find(current Module, get(dbeAttrDefNameList, get(dbeAttrDefNameList)))
AttrType at = find(current Module, ad.typeName "")
string strDefVal = "", strAttrType = "", s = ""
int iAttrChar = 0, iAttrValid = 0, iProperty = 0, iAffects = 0
if (ad.system)
iAttrChar = 1
else
iAttrChar = 4
if (ad.hidden)
iAttrChar = iAttrChar | 2
set(dbeAttrCharacter, iAttrChar)
if (ad.object)
iAttrValid = 2
if (ad.module)
iAttrValid = iAttrValid | 1
set(dbeAttrValidity, iAttrValid)
if (ad.inherit)
iProperty = 1
if (ad.multi)
iProperty = iProperty | 2
set(dbeAttrProperty, iProperty)
if (!ad.nobars)
iAffects = 1
if (!ad.nochanges)
iAffects = iAffects | 2
if (!ad.nohistory)
iAffects = iAffects | 4
set(dbeAttrAffects, iAffects)
if ( null at )
{ strAttrType = "Unable to determine type of attribute"
set(dbeAttrType, strAttrType)
return
}
strAttrType = at.type ""
if ( at.type == attrInteger )
{ int i
if ( at.minValue )
{ i = at.minValue
s = s "Min > " i "\n"
}
if ( at.maxValue )
{ i = at.maxValue
s = s "Max < " i "\n"
}
}
else if ( at.type == attrReal )
{ real r
if ( at.minValue )
{ r = at.minValue
s = s "Min > " r "\n"
}
if ( at.maxValue )
{ r = at.maxValue
s = s "Max < " r "\n"
}
}
else if ( at.type == attrDate )
{ Date d
if ( at.minValue )
{ d = at.minValue
s = s "Min > " d "\n"
}
if ( at.maxValue )
{ d = at.maxValue
s = s "Max < " d "\n"
}
}
else if ( at.type == attrEnumeration )
{ string strAttrTypeName = at.name
strAttrType = strAttrType ": " strAttrTypeName
int i
for ( i = 0; i < at.size; ++i )
s = s at.strings[i] "\n"
}
set(dbeAttrType, strAttrType)
set(dbeAttrTypeList, s)
if (ad.defval)
{ if (strDefVal == "")
strDefVal = ad.defval
set (dbeDefaultValue, strDefVal)
}
else
set (dbeDefaultValue, "")
// Ausgabe in File
// output << ad.name"\n"
// output << s"\n"
} // doSetAttrTypes
void cbDoSetAttrTypes(DBE dbeKlick, int iKlick)
{ doSetAttrTypes
} // cbDoSetAttrTypes
void showAttributes()
{ if ( null current Module )
{ ack "This tool must be run within a module..."
halt
}
// Ausgabe in File
// output << "\t\t"(current Module)."Name""\n"
populateLstAttrDef(true)
doSetAttrTypes()
// close output
} // showAttrInvestigatorDB
/////////////////////////////////////////// Definition for Modules
DBE lblOldList, lblNewList
DBE dbeListCurrent, dbeListBaseline // two global lists containing the baseline selected (or current version)
DBE dbeOutFileBrowse, dbeOutFileLabel
DBE dbeChangeBarToggle
DBE dbeShowDiffToggle
Stream outFile
Skip skBaselines = create // cache current baselines
bool bShowDiff
string strCellBorders = "\\clbrdrt\\brdrs\\brdrw15\\brdrcf11 \\clbrdrl\\brdrs\\brdrw15\\brdrcf11 \\clbrdrb\\brdrs\\brdrw15\\brdrcf11 \\clbrdrr\\brdrs\\brdrw15\\brdrcf11 "
string lastHeadingNumber(Object o)
{ Regexp reg = regexp "\\.0-[0-9]+$"
string onum = number o
if (onum[0:0] == "0")
{ return "0"
}
else if (reg onum)
{ int i = start 0
string hd = onum[0:i-1]
while (reg hd)
{ int j = start 0
hd = hd[0:j-1]
}
return hd
}
else
{ return onum
}
} // lastHeadingNumber
bool oleInsDel(Object o1,o2)
{ bool oleRec = false
string modType = ""
int oldOle = oleCount(o2."Object Text")
int newOle = oleCount(o1."Object Text")
if (newOle > oldOle)
{ oleRec = true
modType = "Figure/Table inserted"
}
if (newOle < oldOle)
{ oleRec = true
modType = "Figure/Table deleted"
}
if (oleRec)
{ outFile << "\\trowd \\trgaph108\\trleft-108\\trkeep"
outFile << strCellBorders "\\cellx1026 " strCellBorders "\\cellx2727 " strCellBorders "\\cellx6129 " strCellBorders "\\cellx9531\n"
outFile << "\\intbl " identifier(o1) " section " lastHeadingNumber(o1) "\\cell OLE\\cell " modType "\\cell \\cell\\row\n"
}
return oleRec
} // oleInsDel
bool oleChange(Object o1,o2)
{ int i = oleCount o1."Object Text"
if (i > 0)
{ Buffer b1 = create
Buffer b2 = create
b1 = richTextWithOle o1."Object Text"
b2 = richTextWithOle o2."Object Text"
int l1 = length b1
int l2 = length b2
delete b1
delete b2
if (l1 != l2)
{ outFile << "\\trowd \\trgaph108\\trleft-108\\trkeep"
outFile << strCellBorders "\\cellx1026 " strCellBorders "\\cellx2727 " strCellBorders "\\cellx6129 " strCellBorders "\\cellx9531\n"
outFile << "\\intbl " identifier(o1) " section " lastHeadingNumber(o1) "\\cell OLE\\cell Figure/Table modified\\cell \\cell\\row\n"
accept o1 // set filter
accept o2 // on both objects
return true
}
}
return false
} // oleChange
bool compareObjects(int absno, Object o1, o2, string attr)
{ // function to compare an attribute of two objects with same absolute number
Buffer s1 = create
Buffer s2 = create
Buffer s3 = create
s1 = o1.attr
s2 = o2.attr
if (s1!=s2)
{ outFile << "\\trowd \\trgaph108\\trleft-108\\trkeep"
// if ((attr=="Object Text") && bShowDiff)
if (bShowDiff)
// {
// diff(s3, s2, s1,"\\cf1\\strike ","\\cf3\\ul ")
// outFile << strCellBorders "\\cellx1026 " strCellBorders "\\cellx2727 " strCellBorders "\\cellx9531\n"
// outFile << "\\intbl \\fs16 " identifier(o1) " section " lastHeadingNumber(o1) "\\cell " attr "\\cell " s3 "\\cell " s2 "\\cell\\row\n"
// }
{ diff(s3, s2, s1)
Regexp ct = regexp "colortbl[^}]*}"
string frag
if (ct s3)
{ frag = s3[end 0 + 1:(length s3) - 3]
}
else
{ frag = richTextFragment stringOf(s3)
}
outFile << strCellBorders "\\cellx1026 " strCellBorders "\\cellx2727 " strCellBorders "\\cellx9531\n"
outFile << "\\intbl \\fs16 " identifier(o1) " section " lastHeadingNumber(o1) "\\cell " attr "\\cell " frag "\\cell\\row\n"
}
else
{ outFile << strCellBorders "\\cellx1026 " strCellBorders "\\cellx2727 " strCellBorders "\\cellx6129 " strCellBorders "\\cellx9531\n"
outFile << "\\intbl \\fs16 " identifier(o1) " section " lastHeadingNumber(o1) "\\cell " attr "\\cell " s1 "\\cell " s2 "\\cell\\row\n"
}
accept o1 // set filter
accept o2 // on both objects
delete s1
delete s2
delete s3
return false
}
delete s1
delete s2
delete s3
return true
} // compareObjects
Skip getAbsnos(Module m)
{ // Build a skip list which maps absnos onto their corresponding objects. Also initialize the DXL filter to "reject"
Skip res = create
Object o
for o in m do
{ int a = o."Absolute Number"
reject o // filter those mentioned in report
put(res, a, o)
}
return res
} // getAbsnos
void applyCompareFunction (DB dbKlick)
{ // Main comparison routine: find out which modules to compare
// compare objects present in both, report on
// those present in only one.
string name1, name2, outf
int idx1, idx2
bool updateChangeBars
idx1 = get dbeListCurrent // position in list
idx2 = get dbeListBaseline
name1 = get dbeListCurrent // baseline name
name2 = get dbeListBaseline
outf = get dbeOutFileBrowse
updateChangeBars = get dbeChangeBarToggle
bShowDiff = get dbeShowDiffToggle
if (idx1 < 0 || idx2 < 0) // error checking
{ ack "two selections are needed"
return
}
else if (idx1 == idx2)
{ ack "same selection on both sides"
return
}
Regexp slash = regexp "[\\\\]"
if (!slash outf)
{ outf = currentDirectory "\\" outf
}
Baseline sel1, sel2
outFile = write outf
outFile << "{\\rtf1\\deff0{\\fonttbl{\\f0\\fswiss\\fcharset177 Times New Roman;}}{\\colortbl ;\\red255\\green0\\blue0;\\red0\\green255\\blue0;\\red0\\green0\\blue255;}\n"
outFile << "\\paperw11906\\paperh16838\\margl1134\\margr567\\margt1134\\margb851\\headery567\\footery567\n"
string where = (current Module)."Name"
outFile << "\\ul \\fs24 Modified Objects in Module: " where "\\ul0 \\par \\par\n"
outFile << "\\trowd \\trgaph108\\trleft-108\\trhdr"
outFile << strCellBorders "\\cellx1026 " strCellBorders "\\cellx2727 " strCellBorders "\\cellx6129 " strCellBorders "\\cellx9531\n"
outFile << "\\intbl \\fs20 Identifier\\cell Attribute\\cell Current Baseline\\cell Old Baseline\\cell\\row\n"
string str
for str in skBaselines do // find each baseline
{ Baseline b = key skBaselines // the baseline is the key
string str = (major b) "." (minor b) (suffix b)
if (name1==str) sel1 = b
if (name2==str) sel2 = b
}
progressStart(dbBLCompare, "Baseline Compare", "", 1)
Module old = current
Module b1, b2
if (idx1==0)
b1 = old // i.e. the current Module
else
{ progressMessage("Load First Baseline Module")
b1 = load(sel1, true) // load the baselines on the screen
}
progressStop()
progressStart(dbBLCompare, "Baseline Compare", "", 1)
if (idx2==0)
b2 = old // i.e.e the current Module
else
{ progressMessage("Load Second Baseline Module")
b2 = load(sel2, true)
}
progressStop()
if (updateChangeBars and (idx1 == 0))
{ AttrDef atcb
atcb = find(b1,"ChangeBar")
if (null atcb)
{ updateChangeBars = false
ack "No ChangeBar attribute in current module"
}
else
{ atcb = find(b1,"WordDocChangeLog")
if (!null atcb)
{ b1."WordDocChangeLog" = outf
}
}
}
else if (updateChangeBars)
{ updateChangeBars = false
ack "Can only update ChangeBar in current module"
}
Skip skCompAttributes = create
string aName
AttrDef atb1,atb2
int i, iSkip = 0, iElems = noElems (dbeAttrDefNameList)
bool bCheck
for (i=0;i<iElems;i++)
{ bCheck = getCheck (dbeAttrDefNameList, i)
if (bCheck)
{ aName = get (dbeAttrDefNameList, i)
atb1 = find(b1,aName)
atb2 = find(b2,aName)
if ((null atb1) or (null atb2))
{ if (null atb1)
infoBox aName " not in later baseline"
else
infoBox aName " not in earlier baseline"
}
else
put(skCompAttributes, iSkip++, aName)
}
}
current = b1 // make sure filtering is off
filtering off // on both sides.
current = b2
filtering off
current = old
Skip absno1 = getAbsnos b1 // build caches of absnos -> objects
Skip absno2 = getAbsnos b2
Object o1, o2
int iObj=0, iMaxObj=0, diffs=0
bool StartInsert = true
for o1 in absno1 do // loop through side 1
iMaxObj++
progressStart(dbBLCompare, "Baseline Compare", "", iMaxObj)
progressMessage("Compare selected attributes of all objects by Identifier")
for o1 in absno1 do // loop through side 1
{ progressStep(iObj++)
Object o2
int i = (int key absno1)
if (find(absno2, i, o2)) // absno exists in other baseline
{ bool ChangeFound = false
for aName in skCompAttributes do
{ ChangeFound = !compareObjects(i, o1, o2, aName) || ChangeFound
}
ChangeFound = oleInsDel(o1,o2) || ChangeFound
if (!ChangeFound)
{ ChangeFound = oleChange(o1,o2)
}
if (ChangeFound)
{ diffs++ // found a difference
if (updateChangeBars)
{ o1."ChangeBar" = true
}
}
else if (updateChangeBars)
{ o1."ChangeBar" = false
}
delete(absno2, i) // remove from dbeListBaseline
}
else
{ if (StartInsert)
{ outFile << "\\pard\\par\\ul \\fs24 Inserted Objects\\ul0\\par \\par "
StartInsert = false
}
outFile << "\\fs20" identifier(o1) " section " lastHeadingNumber(o1) "\\par "
accept o1
if (updateChangeBars)
{ o1."ChangeBar" = true
}
diffs++
}
}
progressStop()
raise (dbBLCompare)
infoBox "Baseline Compare has finished"
if (StartInsert)
{ outFile << "\\pard\\par\\ul \\fs24 Inserted Objects\\ul0\\par \\par "
}
outFile << "\n\\par\\ul \\fs24 Deleted Objects\\ul0\\par \\par "
for o2 in absno2 do // now we can check for objects not in dbeListCurrent
{ int i = (int key absno2)
outFile << "\\fs20" identifier(o2) " section " lastHeadingNumber(o2) "\\par "
accept o2
diffs++
}
delete absno1 // delete caches
delete absno2
delete skCompAttributes
bool doFilter // set to true if differences
if (diffs==0)
{ outFile << "\n\\par \\fs24 no differences found\\par "
doFilter=false
}
else // set filtering on in baselines
{ if (diffs==1)
outFile << "\n\\par \\fs24 one difference found\\par "
else
outFile << "\n\\par \\fs24 " diffs " differences found\\par "
doFilter=true
}
outFile << "\\par }"
close(outFile)
current = b1 // set filters
if (b1 != old)
close b1
// filtering doFilter
// refresh current
current = b2
if (b2 != old)
close b2
// filtering doFilter
// refresh current
current = old // return to former current module
} // applyCompareFunction
//// MAIN PROGRAM ////////////////////////
Module m = current // check calling context
if (null m)
{ ack "program requires current Module"
halt
}
Baseline b
int i=0
for b in m do // count number of baselines
{ i++
}
if (i==0)
{ ack "no baselines to compare"
halt
}
// Now make a dialog for selecting two baselines for comparison
string where = (current Module)."Name"
dbBLCompare = create "Your Company Baseline Compare V. 1.0 startet at Module: \"" where "\""
string strEmptyArr[] = {}
dbeListCurrent = list(dbBLCompare, "Current/Baseline:", 300, i+1 <? 5, strEmptyArr) // make maximum size of 5 elements
dbeListCurrent->"right"->"unattached" // make lists side by side
dbeListBaseline = list(dbBLCompare, "Baseline to compare with:", 300, i+1 <? 5, strEmptyArr)
dbeListBaseline->"left"->"flush"->dbeListCurrent
dbeListBaseline->"top"->"aligned"->dbeListCurrent
dbeListBaseline->"right"->"unattached"
separator (dbBLCompare)
dbeAttrDefNameList = listView(dbBLCompare, listViewOptionCheckboxes , 250, 14, DUMMY_LIST)
dbeAttrDefNameList->"left"->"form"
dbeAttrDefNameList->"right"->"unattached"
dbeAttrAffects = checkBox(dbBLCompare, "", strAffectsArr, 0)
dbeAttrAffects->"top"->"aligned"->dbeAttrDefNameList
dbeAttrAffects->"left"->"flush"->dbeAttrDefNameList
dbeAttrAffects->"right"->"unattached"
inactive (dbeAttrAffects)
dbeAttrCharacter = checkBox(dbBLCompare, "", strCharacterArr, 0)
dbeAttrCharacter->"top"->"flush"->dbeAttrAffects
dbeAttrCharacter->"left"->"flush"->dbeAttrDefNameList
dbeAttrCharacter->"right"->"unattached"
inactive (dbeAttrCharacter)
dbeAttrValidity = checkBox(dbBLCompare, "valid for: ", strValidityArr, 0)
dbeAttrValidity->"top"->"flush"->dbeAttrCharacter
dbeAttrValidity->"left"->"flush"->dbeAttrDefNameList
dbeAttrValidity->"right"->"unattached"
inactive (dbeAttrValidity)
dbeAttrProperty = checkBox(dbBLCompare, "Properties: ", strPropertyArr, 0)
dbeAttrProperty->"top"->"flush"->dbeAttrValidity
dbeAttrProperty->"left"->"flush"->dbeAttrDefNameList
dbeAttrProperty->"right"->"unattached"
inactive (dbeAttrProperty)
dbeAttrType = field (dbBLCompare, "Type: ", "", 27, true)
dbeAttrType->"top"->"spaced"->dbeAttrProperty
dbeAttrType->"left"->"flush"->dbeAttrDefNameList
dbeAttrType->"right"->"unattached"
dbeDefaultValue = field (dbBLCompare, "Default value:", "", 21, true)
dbeDefaultValue->"top"->"flush"->dbeAttrType
dbeDefaultValue->"left"->"flush"->dbeAttrDefNameList
dbeDefaultValue->"right"->"unattached"
dbeAttrTypeList = text(dbBLCompare, "Possible values or defined borders:", "", 215, 142, true)
dbeAttrTypeList->"top"->"spaced"->dbeDefaultValue
dbeAttrTypeList->"left"->"flush"->dbeAttrDefNameList
dbeAttrTypeList->"right"->"unattached"
//dbeAttrTypeList->"bottom"->"unattached"
dbeAttrTypeSelect = toggle(dbBLCompare,"show System and Hidden Attributes", true)
dbeAttrTypeSelect->"top"->"flush"->dbeAttrDefNameList
dbeAttrTypeSelect->"left"->"form"
dbeAttrTypeSelect->"right"->"unattached"
dbeAttrTypeSelect->"bottom"->"unattached"
separator (dbBLCompare)
dbeOutFileLabel = label(dbBLCompare, "Output to:")
dbeOutFileBrowse = fileName(dbBLCompare, "D:\\Project - DOORS Demonstration\\BL_Comp_Result.rtf", "*.rtf", "Rich Text files", false)
dbeChangeBarToggle = toggle(dbBLCompare,"Update ChangeBar attribute", false)
beside (dbBLCompare)
dbeShowDiffToggle = toggle(dbBLCompare,"Show Object Text changes as markup", true)
// dummy
DBE dbeDummy = label(dbBLCompare, "")
dbeDummy->"top"->"spaced"->dbeShowDiffToggle
dbeDummy->"left"->"form"
// Copyright
DBE dbeCopyRight = label(dbBLCompare, "Copyright (C) Your Company Your Town 2005-2007 Confidential. All rights reserved.")
dbeCopyRight->"bottom"->"spaced"->dbeDummy
dbeCopyRight->"left"->"form"
apply(dbBLCompare, "Compare Now", applyCompareFunction)
set(dbeAttrDefNameList, cbDoSetAttrTypes, doNothing, doNothing)
set(dbeAttrTypeSelect, cbSystemSelect)
realize (dbBLCompare, 0, 0) // we realize so that the lists can be populated using insert
insertColumn(dbeAttrDefNameList, 0, "Attribute Name", 200, iconNone)
for b in m do // fill up the baselines skip list with current baselines
{ string str = (major b) "." (minor b) (suffix b)
put(skBaselines, b, str)
insert(dbeListCurrent, 0, str)
insert(dbeListBaseline, 0, str)
}
insert(dbeListCurrent, 0, "current") // put current at head of lists
set(dbeListCurrent, 0)
insert(dbeListBaseline, 0, "current")
set(dbeListBaseline, 1)
showAttributes()
show dbBLCompare // off we go.......
// end of BaselineCompare.dxl
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...
}
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.