DXL - Capturing the "Previous" baseline (not necessarily the latest one)

As the subject of this post suggest, this is with regard to baselines. This is what I am trying to do.

I would like to pass in a baseline into a function and get the baseline immediately preceding the one
passed into the function. Does such a function exist? I have looked at the DXL reference manual
but the best I could find was getMostRecentBaseline (Module m). This function does not really serve the purpose
though. I know there are a plenty of undocumented functions. Hence, I figured I should probably ask on this
forum.

I could always create this function but in the interest of time, I wanted to ask about the existence of
such a function before trying to create one.. Any input would be appreciated. Thank you in advance.
PranavC - Tue Aug 18 10:32:13 EDT 2009

Re: DXL - Capturing the "Previous" baseline (not necessarily the latest one)
Peter_Albert - Tue Aug 18 10:57:38 EDT 2009

I am not aware of a built-in function for this task, but attached is a set of little baseline-related routines. 'Baseline getPreviousBaseline(Module m, string baseType)' might be interesting for you. As it is, it takes a Module handle as input, which might be the current version or any baseline of a Module, and the variable "baseType" which accepts the values "Major", "Minor" or "Any". Consequently, the function returns the previous major, minor or any baseline.

Hope that helps,

Peter



// Find previous baseline (Major / Minor / Any) 
/* Find the baseline previous to the current. Allow searching the previous minor or major baseline. */ string version(Module m, Baseline b) 
{ 

if (

null m)
{

return 
"null Module"
} string val = versionString( moduleVersion( module fullName m, b ) ) 

return val 
}   bool isMinor(Baseline b) 
{

return (

null suffix b)
}   bool isMajor(Baseline b) 
{

return (

null suffix b && minor b == 0)
}   bool baselineEqual(Baseline a, Baseline b) 
{ 

if (

null a && 

null b)
{

return 

false
} 

if (

null a || 

null b)
{

return 

false
} bool returnVal = ( major a == major b && minor a == minor b && suffix a == suffix b ) 

return returnVal 
}   Baseline getPreviousBaseline(Module m, string baseType) 
{ 
// baseType = "Major" --> find last Major baseline 
// baseType = "Minor" --> find last Minor baseline 
// baseType = "Any"   --> find the most recent baseline 
//print dxlHere() " BaseType: " baseType "\n" Baseline b, prevBase, prevMajor, prevMinor Baseline callBaseline = baseline moduleVersion m prevBase = 

null prevMajor = 

null prevMinor = 

null 

for b in m 

do 
{ 
// Loop through the baselines until we reach the 
// baseline version of the calling Module. 
// Thus we don't have to worry if the calling 
// Module is the current Version (i.e. not baselined). 
// In that case prevBase will just be the most recent baseline. 

if (baselineEqual(b, callBaseline))
{

break
} prevBase = b 

if (isMinor b)
{prevMinor = b
} 

if (isMajor b)
{prevMajor = b
} 
} 

if (baseType == 
"Major")
{

return prevMajor
} 

if (baseType == 
"Minor")
{

return prevMinor
} 

return prevBase 
}   Baseline getPreviousBaseline(Module m) 
{ 

return getPreviousBaseline(m, 
"Any") 
}

Re: DXL - Capturing the "Previous" baseline (not necessarily the latest one)
PranavC - Tue Aug 18 11:15:31 EDT 2009

Peter_Albert - Tue Aug 18 10:57:38 EDT 2009
I am not aware of a built-in function for this task, but attached is a set of little baseline-related routines. 'Baseline getPreviousBaseline(Module m, string baseType)' might be interesting for you. As it is, it takes a Module handle as input, which might be the current version or any baseline of a Module, and the variable "baseType" which accepts the values "Major", "Minor" or "Any". Consequently, the function returns the previous major, minor or any baseline.

Hope that helps,

Peter



// Find previous baseline (Major / Minor / Any) 
/* Find the baseline previous to the current. Allow searching the previous minor or major baseline. */ string version(Module m, Baseline b) 
{ 

if (

null m)
{

return 
"null Module"
} string val = versionString( moduleVersion( module fullName m, b ) ) 

return val 
}   bool isMinor(Baseline b) 
{

return (

null suffix b)
}   bool isMajor(Baseline b) 
{

return (

null suffix b && minor b == 0)
}   bool baselineEqual(Baseline a, Baseline b) 
{ 

if (

null a && 

null b)
{

return 

false
} 

if (

null a || 

null b)
{

return 

false
} bool returnVal = ( major a == major b && minor a == minor b && suffix a == suffix b ) 

return returnVal 
}   Baseline getPreviousBaseline(Module m, string baseType) 
{ 
// baseType = "Major" --> find last Major baseline 
// baseType = "Minor" --> find last Minor baseline 
// baseType = "Any"   --> find the most recent baseline 
//print dxlHere() " BaseType: " baseType "\n" Baseline b, prevBase, prevMajor, prevMinor Baseline callBaseline = baseline moduleVersion m prevBase = 

null prevMajor = 

null prevMinor = 

null 

for b in m 

do 
{ 
// Loop through the baselines until we reach the 
// baseline version of the calling Module. 
// Thus we don't have to worry if the calling 
// Module is the current Version (i.e. not baselined). 
// In that case prevBase will just be the most recent baseline. 

if (baselineEqual(b, callBaseline))
{

break
} prevBase = b 

if (isMinor b)
{prevMinor = b
} 

if (isMajor b)
{prevMajor = b
} 
} 

if (baseType == 
"Major")
{

return prevMajor
} 

if (baseType == 
"Minor")
{

return prevMinor
} 

return prevBase 
}   Baseline getPreviousBaseline(Module m) 
{ 

return getPreviousBaseline(m, 
"Any") 
}

Hello Peter,
THANK YOU VERY MUCH!!! This is perfect. This is exactly what I need. Thank you once again.

Regards,

Pranav

Re: DXL - Capturing the "Previous" baseline (not necessarily the latest one)
llandale - Tue Aug 18 16:50:09 EDT 2009

Peter_Albert - Tue Aug 18 10:57:38 EDT 2009
I am not aware of a built-in function for this task, but attached is a set of little baseline-related routines. 'Baseline getPreviousBaseline(Module m, string baseType)' might be interesting for you. As it is, it takes a Module handle as input, which might be the current version or any baseline of a Module, and the variable "baseType" which accepts the values "Major", "Minor" or "Any". Consequently, the function returns the previous major, minor or any baseline.

Hope that helps,

Peter



// Find previous baseline (Major / Minor / Any) 
/* Find the baseline previous to the current. Allow searching the previous minor or major baseline. */ string version(Module m, Baseline b) 
{ 

if (

null m)
{

return 
"null Module"
} string val = versionString( moduleVersion( module fullName m, b ) ) 

return val 
}   bool isMinor(Baseline b) 
{

return (

null suffix b)
}   bool isMajor(Baseline b) 
{

return (

null suffix b && minor b == 0)
}   bool baselineEqual(Baseline a, Baseline b) 
{ 

if (

null a && 

null b)
{

return 

false
} 

if (

null a || 

null b)
{

return 

false
} bool returnVal = ( major a == major b && minor a == minor b && suffix a == suffix b ) 

return returnVal 
}   Baseline getPreviousBaseline(Module m, string baseType) 
{ 
// baseType = "Major" --> find last Major baseline 
// baseType = "Minor" --> find last Minor baseline 
// baseType = "Any"   --> find the most recent baseline 
//print dxlHere() " BaseType: " baseType "\n" Baseline b, prevBase, prevMajor, prevMinor Baseline callBaseline = baseline moduleVersion m prevBase = 

null prevMajor = 

null prevMinor = 

null 

for b in m 

do 
{ 
// Loop through the baselines until we reach the 
// baseline version of the calling Module. 
// Thus we don't have to worry if the calling 
// Module is the current Version (i.e. not baselined). 
// In that case prevBase will just be the most recent baseline. 

if (baselineEqual(b, callBaseline))
{

break
} prevBase = b 

if (isMinor b)
{prevMinor = b
} 

if (isMajor b)
{prevMajor = b
} 
} 

if (baseType == 
"Major")
{

return prevMajor
} 

if (baseType == 
"Minor")
{

return prevMinor
} 

return prevBase 
}   Baseline getPreviousBaseline(Module m) 
{ 

return getPreviousBaseline(m, 
"Any") 
}

Be advised that the 'for b in m do' loop inside your function will in fact corrupt any such 'for b in m do' loop in the calling program. I hate it when that happens. In fact, I hated it when it DID happen, took me days to find the bug. You cannot nest such loops. Since a 'for b in m do' loop is by necessity a common construct in baseline functions, calling programs should routinely stage BL handles in a Skip, such as this:


Baseline b Module   mod = current Skip  skpBLs = create() 
// KEY: 'int' sequencer; DATA: 'Baseline' handle 

int   Sequencer = 0    
// insures BLs are retrieved from Skip in original order 

for b in m 

do 
{  put(skpBLs, Sequencer++, b) 
}   

for b in skpBLs 

do 
{  Deal with 

this baseline, calling perhaps baselineEqual() 
} delete(skpBLs)


This nesting problem is also true for 'Links', and I don't recall for what else. Since I have a massive library that does all this weird stuff, I routinely stage what I'm dealing with in such Skips.

Understand also that your 'baselineEqual()' function will report a false positive if you get a baseline from different modules, which have the same major/minor/suffix designations.

  • Louie

Re: DXL - Capturing the "Previous" baseline (not necessarily the latest one)
Peter_Albert - Wed Aug 19 04:09:46 EDT 2009

llandale - Tue Aug 18 16:50:09 EDT 2009
Be advised that the 'for b in m do' loop inside your function will in fact corrupt any such 'for b in m do' loop in the calling program. I hate it when that happens. In fact, I hated it when it DID happen, took me days to find the bug. You cannot nest such loops. Since a 'for b in m do' loop is by necessity a common construct in baseline functions, calling programs should routinely stage BL handles in a Skip, such as this:


Baseline b Module   mod = current Skip  skpBLs = create() 
// KEY: 'int' sequencer; DATA: 'Baseline' handle 

int   Sequencer = 0    
// insures BLs are retrieved from Skip in original order 

for b in m 

do 
{  put(skpBLs, Sequencer++, b) 
}   

for b in skpBLs 

do 
{  Deal with 

this baseline, calling perhaps baselineEqual() 
} delete(skpBLs)


This nesting problem is also true for 'Links', and I don't recall for what else. Since I have a massive library that does all this weird stuff, I routinely stage what I'm dealing with in such Skips.

Understand also that your 'baselineEqual()' function will report a false positive if you get a baseline from different modules, which have the same major/minor/suffix designations.

  • Louie

Hi Louie,

thank you for pointing out this bug. I was not aware of it.

Although you referred to loops calling the routine, I modified the script below to also use a skip list and added a note to point out this limitation.

As for comparing baselines, I might understand it wrongly, but Baseline handles themselves are strange beasts. As far as I currently see it, a baseline handle is not connected to any Module; you can in fact create a non-null valid baseline handle with e.g. 'Baseline b = baseline(100, 10, "hello world")' regardless of whether the baseline actually exists in the current or any other Module. Strange enough: I just realized that 'suffix(b)' always returns the correct value, while 'major(b)' and 'minor(b)' create a DXL error when there is no current Module (at least in DOORS v7.1).

Only as a ModuleVersion a baseline actually comes to life. Hence, comparing just two baseline handles can not take into account a related module, as the baseline handle exists w/o reference to a module. With other words, I don't think it is possible to retrieve information about the module from the baseline handle itself.

Again, I am not sure I understand baseline handles completely and correctly, so any correction of the above is welcomed.

Below is the modified script.

Regards,

Peter



// Find previous baseline (Major / Minor / Any) 
/* Find the baseline previous to the current. Allow searching the previous minor or major baseline. Note: Louie Landale pointed to an important fact in the IBM forum: You can not nest 'for Baseline b in Module m' loops, attempting to do so results in a DOORS crash. Conesquently, all loops over baselines should be realised in three steps: first collecting all baselines in a Skip list, secondly looping over the baselines in the Skip lsit, thirdly deleting the Skip list. See example below:. Example: Loop over all baselines in module, and for each baseline, report the previous major baseline: #include <baselines.inc> Module m = current Baseline b, c Skip skpBLs = create() int iBL = 0 for b in m do {put(skpBLs, iBL++, b)} for b in skpBLs do { m = load(m, b, false) c = getPreviousBaseline(m, "Major") print version(m,b) ": " version(m,c) "\n" close m } delete(skpBLs) */ string version(Module m, Baseline b) 
{ string val 

if (

null b)
{val =  
"Null Baseline"
} 

else 

if (

null m)
{val =  
"Null Module"
} 

else 

if (!baselineExists(m, b)) 
{val = 
"Baseline " (major b) 
"." (minor b) 
" " (suffix b) 
""
//- 
" does not exist in module '" (name m) 
"'"
} 

else 
{val = versionString(moduleVersion(module fullName m, b))
} 

return val 
}   bool isMinor(Baseline b)
{

return (

null suffix b)
}   bool isMajor(Baseline b) 
{ 
// Note that the 'minor' and 'major' perms require a current Module, 
// so the routine alsways return false in the admittedly strange case that 
// there is no current Module but a Baseline 

if (

null current Module)
{

return 

false
} 

else 
{

return (

null suffix b && minor b == 0)
} 
}   bool baselineEqual(Baseline a, Baseline b) 
{ 
// Note that the handle to a Baseline itself is independant of any module 
// You can actually create non-null baseline handles without referring 
// to any module. This routine just compares baseline handles, and as such 
// will return true for baselines from two different modules which have the 
// same major and minor number and suffix. 
// Compare ModuleVersions if you have to compare baselines from different 
// Modules 
//  
// Note also that the 'minor' and 'major' perms require a current Module, 
// so the routine alsways return false in the admittedly strange case that 
// there is no current Module but two baselines to compare Module mod = current Module 

if (

null mod)
{

return 

false
} 

if (

null a)
{

return 

false
} 

if (

null b)
{

return 

false
} bool returnVal = ( major a == major b && minor a == minor b && suffix a == suffix b ) 

return returnVal 
}   Baseline getPreviousBaseline(Module m, string baseType) 
{ 
// baseType = "Major" --> find last Major baseline 
// baseType = "Minor" --> find last Minor baseline 
// baseType = "Any"   --> find the most recent baseline 
//print dxlHere() " BaseType: " baseType "\n" Skip skpBLs = create() 

int iBL = 0 Baseline b, prevBase, prevMajor, prevMinor Baseline callBaseline = baseline moduleVersion m 

for b in m 

do 
{put(skpBLs, iBL++, b)
} prevBase = 

null prevMajor = 

null prevMinor = 

null 

for b in skpBLs 

do 
{ 
// Loop through the baselines until we reach the 
// baseline version of the calling Module. 
// Thus we don't have to worry if the calling 
// Module is the current Version (i.e. not baselined). 
// In that case prevBase will just be the most recent baseline. 

if (baselineEqual(b, callBaseline))
{

break
} prevBase = b 

if (isMinor b)
{prevMinor = b
} 

if (isMajor b)
{prevMajor = b
} 
} 
// Loop through the baselines delete(skpBLs) 

if (baseType == 
"Major")
{

return prevMajor
} 

if (baseType == 
"Minor")
{

return prevMinor
} 

return prevBase 
}   Baseline getPreviousBaseline(Module m) 
{ 

return getPreviousBaseline(m, 
"Any") 
}

Re: DXL - Capturing the "Previous" baseline (not necessarily the latest one)
llandale - Wed Aug 19 13:58:32 EDT 2009

Peter_Albert - Wed Aug 19 04:09:46 EDT 2009
Hi Louie,

thank you for pointing out this bug. I was not aware of it.

Although you referred to loops calling the routine, I modified the script below to also use a skip list and added a note to point out this limitation.

As for comparing baselines, I might understand it wrongly, but Baseline handles themselves are strange beasts. As far as I currently see it, a baseline handle is not connected to any Module; you can in fact create a non-null valid baseline handle with e.g. 'Baseline b = baseline(100, 10, "hello world")' regardless of whether the baseline actually exists in the current or any other Module. Strange enough: I just realized that 'suffix(b)' always returns the correct value, while 'major(b)' and 'minor(b)' create a DXL error when there is no current Module (at least in DOORS v7.1).

Only as a ModuleVersion a baseline actually comes to life. Hence, comparing just two baseline handles can not take into account a related module, as the baseline handle exists w/o reference to a module. With other words, I don't think it is possible to retrieve information about the module from the baseline handle itself.

Again, I am not sure I understand baseline handles completely and correctly, so any correction of the above is welcomed.

Below is the modified script.

Regards,

Peter



// Find previous baseline (Major / Minor / Any) 
/* Find the baseline previous to the current. Allow searching the previous minor or major baseline. Note: Louie Landale pointed to an important fact in the IBM forum: You can not nest 'for Baseline b in Module m' loops, attempting to do so results in a DOORS crash. Conesquently, all loops over baselines should be realised in three steps: first collecting all baselines in a Skip list, secondly looping over the baselines in the Skip lsit, thirdly deleting the Skip list. See example below:. Example: Loop over all baselines in module, and for each baseline, report the previous major baseline: #include <baselines.inc> Module m = current Baseline b, c Skip skpBLs = create() int iBL = 0 for b in m do {put(skpBLs, iBL++, b)} for b in skpBLs do { m = load(m, b, false) c = getPreviousBaseline(m, "Major") print version(m,b) ": " version(m,c) "\n" close m } delete(skpBLs) */ string version(Module m, Baseline b) 
{ string val 

if (

null b)
{val =  
"Null Baseline"
} 

else 

if (

null m)
{val =  
"Null Module"
} 

else 

if (!baselineExists(m, b)) 
{val = 
"Baseline " (major b) 
"." (minor b) 
" " (suffix b) 
""
//- 
" does not exist in module '" (name m) 
"'"
} 

else 
{val = versionString(moduleVersion(module fullName m, b))
} 

return val 
}   bool isMinor(Baseline b)
{

return (

null suffix b)
}   bool isMajor(Baseline b) 
{ 
// Note that the 'minor' and 'major' perms require a current Module, 
// so the routine alsways return false in the admittedly strange case that 
// there is no current Module but a Baseline 

if (

null current Module)
{

return 

false
} 

else 
{

return (

null suffix b && minor b == 0)
} 
}   bool baselineEqual(Baseline a, Baseline b) 
{ 
// Note that the handle to a Baseline itself is independant of any module 
// You can actually create non-null baseline handles without referring 
// to any module. This routine just compares baseline handles, and as such 
// will return true for baselines from two different modules which have the 
// same major and minor number and suffix. 
// Compare ModuleVersions if you have to compare baselines from different 
// Modules 
//  
// Note also that the 'minor' and 'major' perms require a current Module, 
// so the routine alsways return false in the admittedly strange case that 
// there is no current Module but two baselines to compare Module mod = current Module 

if (

null mod)
{

return 

false
} 

if (

null a)
{

return 

false
} 

if (

null b)
{

return 

false
} bool returnVal = ( major a == major b && minor a == minor b && suffix a == suffix b ) 

return returnVal 
}   Baseline getPreviousBaseline(Module m, string baseType) 
{ 
// baseType = "Major" --> find last Major baseline 
// baseType = "Minor" --> find last Minor baseline 
// baseType = "Any"   --> find the most recent baseline 
//print dxlHere() " BaseType: " baseType "\n" Skip skpBLs = create() 

int iBL = 0 Baseline b, prevBase, prevMajor, prevMinor Baseline callBaseline = baseline moduleVersion m 

for b in m 

do 
{put(skpBLs, iBL++, b)
} prevBase = 

null prevMajor = 

null prevMinor = 

null 

for b in skpBLs 

do 
{ 
// Loop through the baselines until we reach the 
// baseline version of the calling Module. 
// Thus we don't have to worry if the calling 
// Module is the current Version (i.e. not baselined). 
// In that case prevBase will just be the most recent baseline. 

if (baselineEqual(b, callBaseline))
{

break
} prevBase = b 

if (isMinor b)
{prevMinor = b
} 

if (isMajor b)
{prevMajor = b
} 
} 
// Loop through the baselines delete(skpBLs) 

if (baseType == 
"Major")
{

return prevMajor
} 

if (baseType == 
"Minor")
{

return prevMinor
} 

return prevBase 
}   Baseline getPreviousBaseline(Module m) 
{ 

return getPreviousBaseline(m, 
"Any") 
}

I notice the bug before, but noticed that there must be A current module, it need not be THE module associated with the baseline.

In the DXL manual, chapter 'Module' section 'Baseline' command 'Get baseline data', the major/minor etc "must be used inside a for b in mod loop". I don't think that's quite true, the 'b' must have come from such a loop but I don't think you still need to be in the loop to determine who created the baseline.

Anyway, yes a 'Baseline' need not exist (yet), but then again it can exist allowing you to get more information from it, but I see you cannot figure out in which module it exists.

Very confusing, I think perhaps there should have been some sort of 'BaselineProposed' data type.

  • Louie

Re: DXL - Capturing the "Previous" baseline (not necessarily the latest one)
Peter_Albert - Thu Aug 20 04:01:48 EDT 2009

llandale - Wed Aug 19 13:58:32 EDT 2009
I notice the bug before, but noticed that there must be A current module, it need not be THE module associated with the baseline.

In the DXL manual, chapter 'Module' section 'Baseline' command 'Get baseline data', the major/minor etc "must be used inside a for b in mod loop". I don't think that's quite true, the 'b' must have come from such a loop but I don't think you still need to be in the loop to determine who created the baseline.

Anyway, yes a 'Baseline' need not exist (yet), but then again it can exist allowing you to get more information from it, but I see you cannot figure out in which module it exists.

Very confusing, I think perhaps there should have been some sort of 'BaselineProposed' data type.

  • Louie

Confusing indeed. I tend to see Baseline handles as nothing but the collection of up to 6 variables: major, minor, suffix, annotation, user and dateOf.

Creating a baseline with the 'baseline' perm just sets the three first variables, trying to get the annotation crashes DOORS.

Looping through the baselines of a module sets all 6 variables, so you can read them with the appropriate perms. The baselines are, however, not related to the module. You can loop through baselines, and then use the baseline handle to load a module version of a totally different module, given that major, minor and suffix are identical.

Peter

Re: DXL - Capturing the "Previous" baseline (not necessarily the latest one)
PranavC - Fri Aug 21 13:28:48 EDT 2009

Peter_Albert - Thu Aug 20 04:01:48 EDT 2009
Confusing indeed. I tend to see Baseline handles as nothing but the collection of up to 6 variables: major, minor, suffix, annotation, user and dateOf.

Creating a baseline with the 'baseline' perm just sets the three first variables, trying to get the annotation crashes DOORS.

Looping through the baselines of a module sets all 6 variables, so you can read them with the appropriate perms. The baselines are, however, not related to the module. You can loop through baselines, and then use the baseline handle to load a module version of a totally different module, given that major, minor and suffix are identical.

Peter

Thank you Louie and Peter. This was VERY helpful for me. I tailored my script to account for the skip lists instead of making the baselineEqual function call directly from the "for b in m" loop.

Regards,

Pranav