DXL Tutorial – Part I

I’ve seen a few DXL guides in my day, and I’ve seen a lot of DXL snippets, but I’ve never seen an in-depth DXL tutorial. I’m writing this to help plug a gap in the world of DOORS and DXL.

DXL coding is like coding in any other type of language, you have to practice it and do it over and over and over again until you learn its intricacies. The problem that DXL has, unlike many languages, is that it only has a reference guide, and not a full API manual. The reference guide assumes that the programmer is only using the guide as a reference, so explanations are generally on the shorter side, and details are generally not always given where they ought to be.

Telelogic wants to sell training, and that’s fine, but in my opinion, they cripple their user guides as a result. I think they could put every ounce of information about DOORS and DXL in their documentation and they would still sell training, as most projects have managers that understand the importance of getting requirements right the first time.

There I go, digressing again.

The reason I bring it up in the first place is that there are just many different places to go to find critical information. Why isn’t the DXL I wrote showing up in my user menu? Why am I getting an error on a print statement? Finding the answers to these questions takes a lot of time, as you may find them on the Telelogic forums, in the reference guide, via a Google search or by studying code yourself, but there isn’t just one or two single places to go.

The purpose of this series is to take a relatively simple script and add on to it and make it robust, providing a great DXL tutorial in the process. I shall do my best to document the reason for every single line of code.

I was recently tasked with finding out which modules in our database have incoming links. So I wrote a simple function to accomplish the task. This series will take that function and expand upon it incrementally, giving it more features.

Please leave me comments and ask as many questions as possible. Also, make some requests for features. We can all try to build this together. Remember, the goal here is to document as much as possible in an easy tutorial—so people can look at this example and see all the basics to lookout for in one place.

I do assume that you have a basic understanding of programming. This isn’t about teaching programming. You should know the difference between an int and a string. You should know the difference between a for loop and a while loop. If you know the basics–if statements, Boolean logic, etc, you will likely be able to learn some DXL from this tutorial.

So without further ado, let’s begin.

For now, I am setting our goal to be finding out if the current module has any objects that contain incoming links. This seems pretty easy overall. We will eventually expand upon it and include every module in a folder, but for right now, we’re going to concentrate on just the current module.

Thus, step one is to open a module.

The first thing to get out of the way is how to format the comments at the beginning of the file. This header information is important in case someone else has to maintain our DXL and/or we ever want to put it in a DOORS menu.

If we want to use this in a DOORS DXL menu, our code must begin with each of the comment styles, in this order.

//

/*
*/

You can run any DXL you want without this at the beginning, but it will never show up in a DOORS menu.

So I’m going to populate this code.

//Module has incoming links.dxl

/*
$FILENAME: Module has incoming links.dxl
$VERSION: 0.1
$DATE_MODIFIED: 2007-09-23
$DESCRIPTION:
The purpose of this DXL is to report whether the current module has any objects with incoming links.
$CHANGE_HISTORY:
2007-09-23: Initial Release
*/

DXL, like C and C++, uses // and /* */ for comments. You can put anything you like in here and you’ll never get errors. The // is for a single line and /* */denotes multi-line comments.

So we’ve got our description. We should save the file as “Module has incoming links.dxl”.

Now let’s actually start some coding.

For now, the requirement is only to determine whether or not any objects have incoming links. We don’t need to count the number of objects, nor do we need any additional link information.

We have two methods of accomplishing this. We can look at every single object in the module one-by-one, or we can apply a filter. The better way to accomplish this is to apply a filter. Before we apply it, we have to define it.

//Declare filter integers for accepted and rejected objects
int iAcc = 0
int iRej = 0

//Turn off current filter
filtering off

//Define the filter
Filter f = hasLinks( linkFilterIncoming, "*" )

The above code will not give any errors in DOORS, but it won’t give any output either. However, I want to discuss what has already been done.

I declared integer variables for the number of objects accepted and rejected by the filter. This is necessary because if 0 objects are accepted, then our module has no objects with incoming links, and we need to know that. We likely won’t use the iRej variable, but we need it because the function that sets the filter requires it. I also initialize the variable because it’s just good practice. Without initializing it first, if I were to say, print iAcc, and it didn’t have a value, the user would get a DXL error.

Notice, also, how DOORS does not end statements with a semicolon. This makes it different than many other languages. If you don’t like this, you may put a semicolon at the end of every statement. DOORS will ignore it, but will still run DXL.

I did turn filtering off in case there is a filter applied. I do this because DOORS can be quirky sometimes and it’s best to be as explicit as possible. I believe you may omit this statement and the code will still work flawlessly, but I prefer to be safe when it comes to DXL.

Finally, notice where we define the actual filter. Notice that Filter is capitalized. When we declared integers, int was not capitalized. The reason for this is that DXL custom types are capitalized. In C, there are strings, reals, ints, bools, etc. If it exists in standard C, then it is not capitalized in DXL. The filter type is not found in C, so Filter must be capitalized, as must other DXL types, such as Module, Link, Object, and so forth.

There is a function for a filter called hasLinks. If you reference the DXL manual, you’ll see that you can filter on linkFilterIncoming, linkFilterOutgoing, or linkFilterBoth. These values correspond to the values in the links tab of the define filter dialog in DOORS.

The “*” means that we are ignoring specific link modules. Instead, we just want to know if there are any incoming links, regardless of which link module those links may be going through. If we wanted to look at a specific link module, the line would change to:

Filter f = hasLinks( linkFilterIncoming, “/path/to/link module/actual link module name” )

Is everyone with me so far? Now we just need to set the filter and turn filtering on and see what we get.

//set filter
set( current Module, f, iAcc, iRej)

The above code sets the filter f in the current Module. It passes the variables iAcc and iRej by reference, so that both iAcc and iRej are updated with the results. (The & symbol in front of iAcc and iRej in the DXL reference manual for this function means that these variables will get updated by the function).

At this point, we could turn filtering on with a line that said, “filtering on,” but there is no need to do so. We have the information we need. You can turn filtering on if you want to do a quick check, as every object should have at least one incoming link.

If any objects were accepted, we know we have incoming links. So we just need to print out whether we do.

( iAcc > 0 ) ? print "true" : print "false"

This is a unary if statement. Since we’re just wanting to do something simple, we can use this method. It is equivalent to the following code.

if ( iAcc > 0 ) {
print "true"
} else {
print "false"
}//end if

The above code, whichever if statement method is used, will print out true or false in the DXL Interaction window, even if the DXL Interaction window is not being displayed. Calling print will always display it.

Since this may be a menu option one day, we shouldn’t use the print statement. So I’m going to change the code.

( iAcc > 0 ) ? ack "true" : ack "false"

Ack is equivalent to msgBox for you VB programmers out there. It displays a dialog box with an OK button. It’s more interactive and user friendly. (I apologize for using buzzwords from the 1990s, but in this case, it’s true. An ack box is generally better to use than a print statement in DXL.)

So for now, we’re done. I’ve included the entire code below. We’re going to add on to it. My plans eventually are to choose an individual module to run this on via a dialog box. Then maybe to choose a folder to run this on. Finally we may output a report to Microsoft Excel. And we’ll do it from scratch.

Next time we’re going to talk about making the above code into a function. This will let us reuse the code in other scripts very easily.

If anyone has any ideas on how to enhance this, or what tutorial features you’d like to see, feel free to comment below.

//Module has incoming links.dxl

/*

$FILENAME: Module has incoming links.dxl
$VERSION: 0.1
$DATE_MODIFIED: 2007-09-24
$DESCRIPTION:
The purpose of this DXL is to report whether the current module has any objects with incoming links.

$CHANGE_HISTORY:
2007-09-24: Initial Release

*/

//Declare filter integers for accepted and rejected objects
int iAcc = 0
int iRej = 0

//Turn off current filter, in case there is one already applied
filtering off

//Define the filter
Filter f = hasLinks( linkFilterIncoming, "*" )

//set filter
set( current Module, f, iAcc, iRej)

( iAcc > 0 ) ? ack "true" : ack "false"

To run this, in the module you’ve opened, choose Tools>DXL Interaction, paste the code, and click Run.

Leave a Reply