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!
Related
Is there a way to get the attributes of a module without reading it?
I need to get that information for about 100 modules and it takes over 10 minutes if I have to read each module
I don't need to actually get the objects just the attributes available in the module
ModuleProperties should be faster. Try sth like this:
Item i = null
ModuleProperties mp = null
string sModuleAttribute = ""
string sError = ""
for i in project "/<myproject>" do {
if (type i == "Formal") {
sError = getProperties (moduleVersion module fullName i, mp)
if (null sError) {
for sModuleAttribute in mp do {
print fullName i "\t" sModuleAttribute "\t" mp.sModuleAttribute "\n"
}
} else {print sError "\n"}
delete mp
}
}
If you are also interested in the existence of attribute definitions for Objects, this might help
Item i = null
ModuleProperties mp = null
AttrDef ad = null
string sError = ""
for i in folder "/<myproject>" do {
if (type i == "Formal") {
sError = getProperties (moduleVersion module fullName i, mp)
if (null sError) {
for ad in mp do {
print fullName i "\t" ad.name "\t" ad.typeName "\t" ad.object "\t" ad.module "\n"
}
} else {print sError}
delete mp
}
}
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'm new to DOORS and DXL scripting (not sure if it'll be needed here or not). What I'm looking to do is create a new column in two separate modules that will copy the Absolute Numbers. I know this sounds simple enough, but what I'm running into an issue with is that I use a tool to convert my modules into a PDF and it combines them into one module before doing so. Doing this messes up the Absolute Numbers and I can't afford to have that happen.
More descriptive:
I have a column that contains the following:
'REQ01: 4' where 'REQ01:' represents the module and '4' represents the Absolute Number. Similarly, I have 'REQ02: 4'. I need to copy those in their respective modules and make sure they don't change after the modules have been combined.
I've tried my hand at some DXL scripting and this is what I came up with:
displayRich("REQ01: " obj."Absolute Number" "")
This appropriately shows the column, but again will not work as the Absolute Number ends up changing when I merge the modules.
Thanks in advanced for your help and I apologize if I left any crucial information out.
Here is the code that ultimately worked for me.
// DXL generated on 11 June 2014 by Attribute DXL wizard, Version 1.0
// The wizard will use the following comments on subsequent runs
// to determine the selected options and attributes. It will not
// take account of any manual changes in the body of the DXL code.
// begin parameters (do not edit)
// One attribute/property per line: true
// Show attribute/property names: false
// Include OLE objects in text: true
// Attribute: Object Text
// end parameters (do not edit)
Module m
AttrDef ad
AttrType at
m = module obj
ad = find(m,attrDXLName)
if(!null ad && ad.object)
{
at = ad.type
if(at.type == attrText)
{
string s
Buffer val = create
Buffer temp = create
ad = find(m,"Object Text")
if(!null ad)
{
probeRichAttr_(obj,"Object Identifier", temp, true)
val += tempStringOf temp
}
obj.attrDXLName = richText (tempStringOf val)
delete val
delete temp
}
}
There's a builtin "Copy Attributes" script which does this. At least in the version installed at my company, it's in the PSToolbox, and also available in the menu PSToolbox/attributes/copy.../betweenattributes... Here you go:
// Copy values from one attribute to another
/*
*/
/*
PSToolbox Tools for customizing DOORS with DXL V7.1
-------------------------------------------------
DISCLAIMER:
This programming tool has been thoroughly checked
and tested at all stages of its production.
Telelogic cannot accept any responsibility for
any loss, disruption or damage to your data or
your computer system that may occur while using
this script.
If you do not accept these conditions, do not use
this customised script.
-------------------------------------------------
*/
if ( !confirm "This script copies values from one attribute to another in the same module.\n" //-
"Use this to assist in changing the types of attributes.\n\n" //-
"It asks you to select the source and destination attributes.\n\n" //-
"It works by ... well, copying attribute values!\n\n" //-
"Continue?"
)
{
halt
}
#include <addins/PSToolbox/utensils/dbs.inc>
const int MAXATTRS = 1000
DB copyAttrValsDB = null
DBE copyAttrValsFrom = null
DBE copyAttrValsTo = null
DBE copyAttrValsConfirm = null
DBE copyAttrValsButt = null
string attrListFrom[MAXATTRS]
string attrListTo[MAXATTRS]
string confirmOpts[] = { "Yes", "Yes to all", "No", "No to all", "Cancel" }
bool confirmDataLoss = true
bool noToDataLoss = false
///////////////////////////////////////////////////////////
// Call-backs
void doAttrValsCopy(DB db) {
// check attributes
string fromAn = attrListFrom[get copyAttrValsFrom]
string toAn = attrListTo [get copyAttrValsTo ]
if ( fromAn == toAn ) {
ack "Cannot copy attribute to itself."
return
}
// get confirmation
if ( !confirm "Confirm copy of attribute '" fromAn "' to attribute '" toAn "'." ) {
return
}
confirmDataLoss = get copyAttrValsConfirm
// do copy
Object o
for o in current Module do
{
Buffer oldVal = create()
Buffer newVal = create()
if ( fromAn == "Object Identifier" ) newVal = identifier(o)
else if ( fromAn == "Object Level" ) newVal = level(o) ""
else if ( fromAn == "Object Number" ) newVal = number(o)
else newVal = richText o.fromAn
oldVal = richText o.toAn
if ( confirmDataLoss && !noToDataLoss && length(oldVal) > 0 && oldVal != newVal )
{
current = o
refresh current
int opt = query("About to lose attribute '" toAn "' = '" stringOf(oldVal) "' on current object.", confirmOpts)
if ( opt == 1 ) confirmDataLoss = false
if ( opt == 2 ) continue
if ( opt == 3 ) noToDataLoss = true
if ( opt == 4 ) return
}
if ( !confirmDataLoss || !noToDataLoss || length(oldVal) == 0 ) o.toAn = richText stringOf(newVal)
delete(oldVal)
delete(newVal)
}
hide copyAttrValsDB
}
///////////////////////////////////////////////////////////
// Main program
int numAttrsFrom = 0
int numAttrsTo = 0
AttrDef ad
for ad in current Module do {
if ( ad.module ) continue
string an = ad.name
if ( canRead (current Module, an) ) attrListFrom[numAttrsFrom++] = an
if ( canWrite(current Module, an) ) attrListTo [numAttrsTo++ ] = an
}
attrListFrom[numAttrsFrom++] = "Object Identifier"
attrListFrom[numAttrsFrom++] = "Object Level"
attrListFrom[numAttrsFrom++] = "Object Number"
copyAttrValsDB = create "Copy attribute values"
copyAttrValsFrom = choice(copyAttrValsDB, "From:", attrListFrom, numAttrsFrom, 0)
copyAttrValsTo = choice(copyAttrValsDB, "To:", attrListTo, numAttrsTo, 0)
copyAttrValsButt = apply (copyAttrValsDB, "Copy", doAttrValsCopy)
copyAttrValsConfirm = toggle(copyAttrValsDB, "Confirm on loss of data", true)
show copyAttrValsDB
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.
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.