Find Words in entire module - ibm-doors

I have skip list contains an ADC, FIFO, DAC, FILO etc.
I want to know whether these words are used in the entire module or not .if used in the module should return the unused words.
I have a program but it is taking too much time to execute.
Please help me with this.
Here is the code :
Skip Search_In_Entire_Module(Skip List)
{
int sKey = 0
Skip sList = create()
string data = ""
string objText1
Object obj
for data in List do
{
int var_count = 0
for obj in m do
{
objText1 = obj."Object Text"
if objText1!=null then
{
if (isDeleted obj){continue}
if (table obj) {continue}
if (row obj) {continue}
if (cell obj) {continue}
Buffer buf = create()
buf = objText1
int index = 0
while(true)
{
index = contains(buf, data, index)
if(0 <= index)
{
index += length(data)
}
else
{
var_count++
break
}
}
delete(buf)
}
}
if (var_count ==0)
{
put(sList,sKey,data)
sKey++
}
}
return sList
}
Unused_Terminolody_Data = Search_In_Entire_Module(Terminology_Data)

Just wondering: why is this in a while loop?
while(true)
{
index = contains(buf, data, index)
if(0 <= index)
{
index += length(data)
}
else
{
var_count++
break
}
}
I would instead just do:
index = contains ( buf, data )
if ( index == -1 ) {
var_count++
}
buf = ""
I would also not keep deleting and recreating the buffer. Create the buffer up where you create the object variable, then set it equal to "" to clear it, then delete it at the end of the program.
Let me know if this helps!

Balthos makes good points, and I think there's a little more you could do. My adaptation of your function follows. Points to note:
I implemented Balthos's suggestions (above) of taking out the
'while' loop, and buffer creation/deletion.
I changed the function signature. Given that Skip lists are passed
by reference, and must be created and deleted outside the function
it's syntactically confusing (to me, anyway) to return them from a
function. So, I pass both skip lists (terms we're seeking, terms not
found) in as function parameters. Please excuse me changing variable
names - it helped me to understand what was going on more quickly.
There's no need to put the Object Text in a string - this is
relatively slow and consumes memory that will not be freed until
DOORS exits. So, I put the Object Text in a buffer earlier in the
function, and search that. The 'if (!null bufObjText)' at my line 34
is equivalent to your 'objText1!=null'. If you prefer, 'if
(bufObjText != null)' does the same.
The conditional 'if (var_count ==0)' is redundant - I moved it's
functions into an earlier 'if' block (my line 40).
I moved the tests for deleted, table, row and cell objects up, so
that they occur before we take the time to fill a buffer with object
text - so that's only done if necessary.
Item 2 probably isn't going to have a performance impact, but the others will. The only quesiton is, how large?
Please let us know if this improves the running time over what you currently have. I don't have a sufficiently large set of sample data to make meaningful comparisons with your code.
Module modCurrent = current
Skip skUnused_Terminology_Data = create
Skip skSeeking_Terminology_Data = create()
put (skSeeking_Terminology_Data, 0, "SPONG")
put (skSeeking_Terminology_Data, 1, "DoD")
void Search_In_Entire_Module(Skip skTermsSought, skTermsNotFound)
{
Object obj
Buffer bufObjText = create()
int intSkipKey = 0
int index = 0
string strSkipData = ""
for strSkipData in skTermsSought do
{
int var_count = 0
bool blFoundTerm = false
for obj in modCurrent do
{
if (isDeleted obj){continue}
if (table obj) {continue}
if (row obj) {continue}
if (cell obj) {continue}
bufObjText = obj."Object Text"
if (!null bufObjText) then
{
Regexp re = regexp2 strSkipData
blFoundTerm = search (re, bufObjText, 0)
if ( blFoundTerm ) {
put(skUnused_Terminology_Data, intSkipKey, strSkipData)
intSkipKey++
}
bufObjText = ""
}
}
delete (bufObjText)
}
Search_In_Entire_Module (skSeeking_Terminology_Data, skUnused_Terminology_Data)
string strNotFound
for strNotFound in skUnused_Terminology_Data do
{
print strNotFound "\n"
}
delete skUnused_Terminology_Data
delete skSeeking_Terminology_Data

Related

Unexpected error "incorrect use of identifier" when running DXL code

I have a script which calls functions from this script:
https://www.baselinesinc.com/dxl-repository/?filerepoaction=showpost&filepost_id=13
which is distributed under the LGPL. I have found several references to this script online, indicating that it works. For my own purposes, I removed the part of the code which executes on load (some 20 lines at the bottom of the file) and converted the file to an .inc, to serve as a library. I haven't done any other changes.
My own script has worked for a few months at this point. But now, all of a sudden, when I try to run it, I get these errors:
-E- DXL: <DOORSImporter\Import_From_Excel.inc:291> incorrect use of identifier (rtfValue)
-E- DXL: <DOORSImporter\Import_From_Excel.inc:292> incorrect use of identifier (nonRTFValue)
-E- DXL: <DOORSImporter\Import_From_Excel.inc:346> incorrect use of identifier (temp)
-E- DXL: <DOORSImporter\Import_From_Excel.inc:464> incorrect use of identifier (columnHeading)
-E- DXL: <DOORSImporter\Import_From_Excel.inc:1127> incorrect use of identifier (cellValue)
-I- DXL: All done. Errors reported: 5. Warnings reported: 0.
Below is a snippet of code which shows this error. I marked lines 291 and 292
bool richTextTruncated(int rowNumber, int columnNumber) {
Buffer rtfValue = create
Buffer nonRTFValue = create
rtfValue = ""
nonRTFValue = ""
rtfValue = copyRichTextFromCell(""intToCol(columnNumber) "" rowNumber"") // get the rich text
rtfValue = trimWhitespace(stripRichText(tempStringOf(rtfValue))) // strip off RTF formatting. <----- 291
nonRTFValue = trimWhitespace(getCellValue(rowNumber, columnNumber)) //<----- 292
if(tempStringOf(rtfValue) != tempStringOf(nonRTFValue)) { // if the two strings aren't equal
delete(rtfValue)
delete(nonRTFValue)
return true // return that text was truncated
}
delete(rtfValue)
delete(nonRTFValue)
return false
}
The function trimWhitespace itself is defined as
string trimWhitespace(string s) so it's OK to assign its output to a buffer.
So this is all very confusing because, like I said, this has worked and the code has not been changed (last check in of the file DOORSImporter\Import_From_Excel.inc is from last November, whereas I have used the script even in January.
Our IT department might have updated DOORS recently, I don't know. I checked the latest version of the dxl reference manual for any recent changes which might have caused this, but I couldn't find any change to the way buffers are handled.
To be fair, I have found working with buffers quite confusing. In my own code, I ended up discarding them altogether. However, the script Import_From_Excel has worked unchanged for a long time now.
Any support with this will be greatly appreciated.
********** Edit 27.02.2020 **************
The function copyRichTextFromCell is defined as below. Its sourced is from the link below.
https://www.baselinesinc.com/dxl-repository/?filerepoaction=showpost&filepost_id=10
string copyRichTextFromCell(string loc) {
if(!getCell(loc)) {
return("error");
}
if(!checkResult(oleMethod(objCell, cMethodSelect))) { // selects the cell
return("error");
}
if(!checkResult(oleMethod(objCell, cMethodCopy))) { // copies the contents of the cell to the clipboard
return("error");
}
return stringOf(richClip)
}
********** Edit 28.02.2020 **************
The function trimWhitespace is as below.
string trimWhitespace(string s) {
int first = 0;
int last = length(s) - 1;
while(last > 0 && (isspace(s[last]) || s[last] == '\n' || s[last] == '\r' || s[last] == '\t')) {
last--;
}
while(isspace(s[first]) && first < last) {
first++;
}
if(s[first:last] == " ") {
return("");
}
return(s[first:last]);
}
While playing around, I discovered that if I modify as below, one of the errors disappears. It is beyond me as to why that might happen, because the code is equivalent, as far as I can tell...
bool richTextTruncated(int rowNumber, int columnNumber) {
Buffer rtfValue = create
Buffer nonRTFValue = create
string fooString
rtfValue = ""
nonRTFValue = ""
rtfValue = copyRichTextFromCell(""intToCol(columnNumber) "" rowNumber"") // get the rich text
fooString = trimWhitespace(stripRichText(tempStringOf(rtfValue)))
rtfValue = fooString // strip off RTF formatting.
fooString = trimWhitespace(getCellValue(rowNumber, columnNumber))
nonRTFValue = fooString
if(tempStringOf(rtfValue) != tempStringOf(nonRTFValue)) { // if the two strings aren't equal
delete(rtfValue)
delete(nonRTFValue)
return true // return that text was truncated
}
delete(rtfValue)
delete(nonRTFValue)
return false
}
So the lines with fooString do not throw an error anymore. In the initial version, these lines were just e.g. rtfValue = trimWhitespace(stripRichText(tempStringOf(rtfValue))) and this would throw an error.

Determining context at a position in file using ANTLR4

I'm trying to write a Language Extension for VS Code in JavaScript and I seem to be missing something.
I have a Lexer.g4 and Parser.g4 for my language and can generate a tree using them.
My issue is that the VS Code API gives me a document and a position in that document (line #, character #). From any of the examples I've looked at for ANTLR4 I can't seem to find any functions generated that take a position in the file and give back the nodes of a tree at that position.
I want to know, for example that the cursor is placed on the name of a function.
Am I supposed to be walking the entire tree and checking the position of tokens to see if they enclose the position I'm in in the editor? Or maybe I'm not using the right tool for the job? I feel like I'm probably missing something more fundamental.
Yes, you have to walk the parse tree to find the context at a given position. This is a pretty simple task and you can see it in action in my ANLTR4 exension for vscode. There are multiple functions returning something useful for a given position. For instance this one:
/**
* Returns the parse tree which covers the given position or undefined if none could be found.
*/
function parseTreeFromPosition(root: ParseTree, column: number, row: number): ParseTree | undefined {
// Does the root node actually contain the position? If not we don't need to look further.
if (root instanceof TerminalNode) {
let terminal = (root as TerminalNode);
let token = terminal.symbol;
if (token.line != row)
return undefined;
let tokenStop = token.charPositionInLine + (token.stopIndex - token.startIndex + 1);
if (token.charPositionInLine <= column && tokenStop >= column) {
return terminal;
}
return undefined;
} else {
let context = (root as ParserRuleContext);
if (!context.start || !context.stop) { // Invalid tree?
return undefined;
}
if (context.start.line > row || (context.start.line == row && column < context.start.charPositionInLine)) {
return undefined;
}
let tokenStop = context.stop.charPositionInLine + (context.stop.stopIndex - context.stop.startIndex + 1);
if (context.stop.line < row || (context.stop.line == row && tokenStop < column)) {
return undefined;
}
if (context.children) {
for (let child of context.children) {
let result = parseTreeFromPosition(child, column, row);
if (result) {
return result;
}
}
}
return context;
}
}

How to handle errors without execution halting

I have a small dxl script and I need to return the number of assigned positions from an array of, let's say, size 20 in which only 10 positions are assigned.
I tried to use noError() and lastError() functions, but after lastError() is called, the script is halted and I can't continue the execution.
Here's my code:
int returnArrayLength(string array[]){
int lengthOfArray = 0,i = 0;
for (i=0; i < sizeof array ; i++){
noError()
if (!null array[i]){
lengthOfArray++
print lengthOfArray
}
if (!null lastError()){
print "Exception caught!" // not printed
break
}
}
return lengthOfArray
}
string labels[6]
labels[0] = "label0"
labels[1] = "label1"
labels[2] = "label2"
labels[3] = "label3"
print returnArrayLength(labels) // not printed
The above code prints the following:
1
2
3
4
How can I resume the execution after the lastError() function is called ?
This was tougher than I thought it would be!
So, as it turns out, an unassigned element error halts the DXL program entirely. So what do we need to do?
Well, we need to run a snippet of code, in it's own environment, and let it crash if it needs to!
To do so, we need to create an eval_, pass it our array, and then have it return_ (which won't be executed if the eval_ fails)
Take a look:
int returnArrayLength(string array[]){
int lengthOfArray = 0,i = 0;
for (i=0; i < sizeof array ; i++){
string scode = "noError()
string ( &passedAr)[] = (addr_ "( ( addr_ array ) int ) ")
string s = passedAr["i"]
lastError()
return_ \"Y\""
if ( ( eval_ scode ) == "Y" ){
lengthOfArray++
print lengthOfArray
} else {
print "Exception caught!" "\n"
break
}
}
return lengthOfArray
}
string labels[6]
labels[0] = "label0"
labels[1] = "label1"
labels[2] = "label2"
labels[3] = "label3"
print returnArrayLength(labels)
What a fantastic little problem.
Resources I used to help solve this:
How to pass an array into an eval_
eval_ , addr_ , and memory leaks
Testing for unassigned variables - This one doesn't quite work because of the nature of arrays, at least as far as I could tell!
In any case, thanks for the challenge!

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!

How to compare two column in a spreadsheet

I have 30 columns and 1000 rows, I would like to compare column1 with another column. IF the value dont match then I would like to colour it red. Below is a small dataset in my spreadsheet:
A B C D E F ...
1 name sName email
2
3
.
n
Because I have a large dataset and I want to storing my columns in a array, the first row is heading. This is what I have done, however when testing I get empty result, can someone correct me what I am doing wrong?
var index = [];
var sheet = SpreadsheetApp.getActiveSheet();
function col(){
var data = sheet.getDataRange().getValues();
for (var i = 1; i <= data.length; i++) {
te = index[i] = data[1];
Logger.log(columnIndex[i])
if (data[3] != data[7]){
// column_id.setFontColor('red'); <--- I can set the background like this
}
}
}
From the code you can see I am scanning whole spreadsheet data[1] get the heading and in if loop (data[3] != data[7]) compare two columns. I do have to work on my colour variable but that can be done once I get the data that I need.
Try to check this tutorial if it can help you with your problem. This tutorial use a Google AppsScript to compare the two columns. If differences are found, the script should point these out. If no differences are found at all, the script should put out the text "[id]". Just customize this code for your own function.
Here is the code used to achieve this kind of comparison
function stringComparison(s1, s2) {
// lets test both variables are the same object type if not throw an error
if (Object.prototype.toString.call(s1) !== Object.prototype.toString.call(s2)){
throw("Both values need to be an array of cells or individual cells")
}
// if we are looking at two arrays of cells make sure the sizes match and only one column wide
if( Object.prototype.toString.call(s1) === '[object Array]' ) {
if (s1.length != s2.length || s1[0].length > 1 || s2[0].length > 1){
throw("Arrays of cells need to be same size and 1 column wide");
}
// since we are working with an array intialise the return
var out = [];
for (r in s1){ // loop over the rows and find differences using diff sub function
out.push([diff(s1[r][0], s2[r][0])]);
}
return out; // return response
} else { // we are working with two cells so return diff
return diff(s1, s2)
}
}
function diff (s1, s2){
var out = "[ ";
var notid = false;
// loop to match each character
for (var n = 0; n < s1.length; n++){
if (s1.charAt(n) == s2.charAt(n)){
out += "–";
} else {
out += s2.charAt(n);
notid = true;
}
out += " ";
}
out += " ]"
return (notid) ? out : "[ id. ]"; // if notid(entical) return output or [id.]
}
For more information, just check the tutorial link above and this SO question on how to compare two Spreadsheets.

Resources