This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Problem with list management...
Started by
gronchi
, Nov 18 2004 12:04
6 replies to this topic
Posted 18 November 2004 - 12:04
Hi to all,
in a script I have to do:
Get a list (strings)
Check every string and
if (length(string)<4) delete string from the list
Well, when 2 or more to-be-deleted string are adjacent the above simple algorithm fail!
That is the second to-be-deleted string will not detected.
Example:
in a script I have to do:
Get a list (strings)
Check every string and
if (length(string)<4) delete string from the list
Well, when 2 or more to-be-deleted string are adjacent the above simple algorithm fail!
That is the second to-be-deleted string will not detected.
Example:
CODE |
//////////////////////////////////////////////////////////////////////////// // // Function: checkListCT // Purpose: This function check a string List and delete those one with lenght < 4 // Input: None // Output: None // //////////////////////////////////////////////////////////////////////////// function checkListCT() NUMBER nProgressive; STRING szProgressive, szCurrentString; LIST listCT; begin // list creation for my example listCT = ListCreate(STRINGLIST); ListAddString(listCT, "1.1"); ListAddString(listCT, "1.2"); ListAddString(listCT, "1.3"); ListAddString(listCT, "1.3.0"); ListAddString(listCT, "1.3.1"); ListAddString(listCT, "1.3.1.12"); ListAddString(listCT, "1.4"); ListAddString(listCT, "1.4.1.7"); ListAddString(listCT, "1.4.2.2"); ListAddString(listCT, "1.4.2.4"); ListAddString(listCT, "1.5"); ListAddString(listCT, "1.5.0"); nProgressive = ListGetFirstString (listCT, szProgressive); while (nProgressive != END_OF_LIST) // remove fictitious string (lenght < 4) from the list ListCurrentString (listCT, szCurrentString); SprintfBox(INFORMATION, "ListCurrentString 1", "ListCurrentString now is: %s\nszProgressiveString now is: %s", szCurrentString, szProgressive); if (StrLengthChars (szProgressive) < 4) then ListDeleteString (listCT); #ifdef DEBUG SprintfBox(WARNING, "checkListCT", "%s is fictitious (lenght < 4) --> removed!", szProgressive); #endif ListCurrentString (listCT, szCurrentString); SprintfBox(INFORMATION, "ListCurrentString 2", "ListCurrentString now is: %s\nszProgressiveString now is: %s", szCurrentString, szProgressive); else #ifdef DEBUG SprintfBox(INFORMATION, "checkListCT", "%s is real!", szProgressive); #endif endif; nProgressive = ListGetNextString (listCT, szProgressive); endwhile; ListDestroy(listCT); end; |
My analysis (comforted by sprintf...):
1. SprintfBox(INFORMATION, "ListCurrentString 1",
ListCurrentString now is: "1.1"
szProgressiveString now is: "1.1"
2. find string "1.1" lenght < 4
3. delete string "1.1"
4. SprintfBox(INFORMATION, "ListCurrentString 2",
ListCurrentString now is: "1.2"
szProgressiveString now is: "1.1"
4. ListGetNextString, repeat while cycle
5. SprintfBox(INFORMATION, "ListCurrentString 1",
ListCurrentString now is: "1.3" <--???
szProgressiveString now is: "1.3" <--???
Where "1.2" string is finished?
Don't try to move ListGetNextString inside the if statment (when string is not deleted branch) because you'll go inside an infinite loop!
Anyone has an idea of what happened?
Solutions? (Apart the way to keep 2 list...)
Thanks to all,
ciao Giuseppe
Edited by gronchi, 18 November 2004 - 13:24.
Posted 18 November 2004 - 13:10
it may be difficult to step through a list when some entries are deleted while stepping through ... the pointer to the current string may get lost or something.
so, it may be a workaround not to delete the strings, but to add the strings you want to another list.
btw: you should destroy the list you've created :-) (listCT <-> listJRE)
so, it may be a workaround not to delete the strings, but to add the strings you want to another list.
btw: you should destroy the list you've created :-) (listCT <-> listJRE)
Gruß / regards
Thomas
Thomas
Posted 18 November 2004 - 15:47
If I'm reading your code correctly:
In step 4 your current string is "1.2"
Then you are calling ListGetNextString which make "1.3" the current string and also assigns this to szProgressive (at the end of the while loop), and also assigns it to szCurrentString (ListCurrentString at the beginning of the while loop)
I guess the solution would be not to advance to the next string (don't call ListGetNextString) if you have deleted an entry in the current loop.
In step 4 your current string is "1.2"
Then you are calling ListGetNextString which make "1.3" the current string and also assigns this to szProgressive (at the end of the while loop), and also assigns it to szCurrentString (ListCurrentString at the beginning of the while loop)
I guess the solution would be not to advance to the next string (don't call ListGetNextString) if you have deleted an entry in the current loop.
Stefan Krüger
InstallSite.org twitter facebook
Posted 18 November 2004 - 16:10
QUOTE (Stefan Krueger @ 2004-11-18 14:47) |
If I'm reading your code correctly: In step 4 your current string is "1.2" Then you are calling ListGetNextString which make "1.3" the current string and also assigns this to szProgressive (at the end of the while loop), and also assigns it to szCurrentString (ListCurrentString at the beginning of the while loop) I guess the solution would be not to advance to the next string (don't call ListGetNextString) if you have deleted an entry in the current loop. |
I have already tried to do that but it doesn't work!
Moving ListGetNextString inside the if statment (when string is not in the delete-branch) you'll go inside an infinite loop!
That is szProgressiveString still remain "1.1"
Maybe it's a sw bug in the funcion...
AnyWay thank's,
Giuseppe
Posted 19 November 2004 - 09:31
Hard to believe. Please double check yur code and make sure it actually gets executed when the string is not deleted. I'd suggest you step through your code with the debugger to see what actually happens.
Stefan Krüger
InstallSite.org twitter facebook
Posted 19 November 2004 - 11:00
Yes hard to believe!
But let me bore you with the bare examples:
I made two blank project differening only in one line code, in the first one the string list is incremented always:
nProgressive = ListGetNextString (listCT, szProgressive);
is out of the if statment
But let me bore you with the bare examples:
I made two blank project differening only in one line code, in the first one the string list is incremented always:
nProgressive = ListGetNextString (listCT, szProgressive);
is out of the if statment
CODE |
///////////////////////////////////////////////////////////////////////////// // // File Name: Setup.rul // // Description: InstallShield script // // Comments: This minimal project is intended for advanced users. To // create a robust project with step-by-step instructions, // use the Project Wizard. // ///////////////////////////////////////////////////////////////////////////// // Include header files ///////////////////////////////////////////////////// #include "ifx.h" NUMBER nProgressive; STRING szProgressive, szCurrentString; LIST listCT; program //////////////////////////////////////////////////////////////////////////// // // Function: checkListCT // Purpose: This function check a string List and delete those one with lenght < 4 // Input: None // Output: None // //////////////////////////////////////////////////////////////////////////// // list creation for my example listCT = ListCreate(STRINGLIST); ListAddString(listCT, "1.1", AFTER); ListAddString(listCT, "1.2", AFTER); ListAddString(listCT, "1.3", AFTER); ListAddString(listCT, "1.3.0", AFTER); ListAddString(listCT, "1.3.1", AFTER); ListAddString(listCT, "1.3.1.12", AFTER); ListAddString(listCT, "1.4", AFTER); ListAddString(listCT, "1.4.1.7", AFTER); ListAddString(listCT, "1.4.2.2", AFTER); ListAddString(listCT, "1.4.2.4", AFTER); ListAddString(listCT, "1.5", AFTER); ListAddString(listCT, "1.5.0", AFTER); nProgressive = ListGetFirstString (listCT, szProgressive); while (nProgressive != END_OF_LIST) // remove fictitious string (lenght < 4) from the list ListCurrentString (listCT, szCurrentString); SprintfBox(INFORMATION, "ListCurrentString 1", "ListCurrentString now is: %s\nszProgressiveString now is: %s", szCurrentString, szProgressive); if (StrLengthChars (szProgressive) < 4) then ListDeleteString (listCT); #ifdef DEBUG SprintfBox(WARNING, "checkListCT", "%s is fictitious (lenght < 4) --> removed!", szProgressive); #endif ListCurrentString (listCT, szCurrentString); SprintfBox(INFORMATION, "ListCurrentString 2", "ListCurrentString now is: %s\nszProgressiveString now is: %s", szCurrentString, szProgressive); else #ifdef DEBUG SprintfBox(INFORMATION, "checkListCT", "%s is real!", szProgressive); #endif endif; nProgressive = ListGetNextString (listCT, szProgressive); endwhile; ListDestroy(listCT); endprogram |
This is the Sprintf layout:
1. SprintfBox(INFORMATION, "ListCurrentString 1",
ListCurrentString now is: "1.1"
szProgressiveString now is: "1.1"
2. find string "1.1" lenght < 4
3. delete string "1.1"
4. SprintfBox(INFORMATION, "ListCurrentString 2",
ListCurrentString now is: "1.2"
szProgressiveString now is: "1.1"
4. ListGetNextString, repeat while cycle
5. SprintfBox(INFORMATION, "ListCurrentString 1",
ListCurrentString now is: "1.3" <--???
szProgressiveString now is: "1.3" <--???
... in the second one the string list is incremented only when there is no deleted string:
nProgressive = ListGetNextString (listCT, szProgressive);
is in the else branch of the if statment
CODE |
///////////////////////////////////////////////////////////////////////////// // // File Name: Setup.rul // // Description: InstallShield script // // Comments: This minimal project is intended for advanced users. To // create a robust project with step-by-step instructions, // use the Project Wizard. // ///////////////////////////////////////////////////////////////////////////// // Include header files ///////////////////////////////////////////////////// #include "ifx.h" NUMBER nProgressive; STRING szProgressive, szCurrentString; LIST listCT; program //////////////////////////////////////////////////////////////////////////// // // Function: checkListCT // Purpose: This function check a string List and delete those one with lenght < 4 // Input: None // Output: None // //////////////////////////////////////////////////////////////////////////// // list creation for my example listCT = ListCreate(STRINGLIST); ListAddString(listCT, "1.1", AFTER); ListAddString(listCT, "1.2", AFTER); ListAddString(listCT, "1.3", AFTER); ListAddString(listCT, "1.3.0", AFTER); ListAddString(listCT, "1.3.1", AFTER); ListAddString(listCT, "1.3.1.12", AFTER); ListAddString(listCT, "1.4", AFTER); ListAddString(listCT, "1.4.1.7", AFTER); ListAddString(listCT, "1.4.2.2", AFTER); ListAddString(listCT, "1.4.2.4", AFTER); ListAddString(listCT, "1.5", AFTER); ListAddString(listCT, "1.5.0", AFTER); nProgressive = ListGetFirstString (listCT, szProgressive); while (nProgressive != END_OF_LIST) // remove fictitious string (lenght < 4) from the list ListCurrentString (listCT, szCurrentString); SprintfBox(INFORMATION, "ListCurrentString 1", "ListCurrentString now is: %s\nszProgressiveString now is: %s", szCurrentString, szProgressive); if (StrLengthChars (szProgressive) < 4) then ListDeleteString (listCT); #ifdef DEBUG SprintfBox(WARNING, "checkListCT", "%s is fictitious (lenght < 4) --> removed!", szProgressive); #endif ListCurrentString (listCT, szCurrentString); SprintfBox(INFORMATION, "ListCurrentString 2", "ListCurrentString now is: %s\nszProgressiveString now is: %s", szCurrentString, szProgressive); else #ifdef DEBUG SprintfBox(INFORMATION, "checkListCT", "%s is real!", szProgressive); #endif nProgressive = ListGetNextString (listCT, szProgressive); endif; endwhile; ListDestroy(listCT); endprogram |
This is the Sprintf layout:
1. SprintfBox(INFORMATION, "ListCurrentString 1",
ListCurrentString now is: "1.1"
szProgressiveString now is: "1.1"
2. find string "1.1" lenght < 4
3. delete string "1.1"
4. SprintfBox(INFORMATION, "ListCurrentString 2",
ListCurrentString now is: "1.2"
szProgressiveString now is: "1.1"
NO --> ListGetNextString
4. repeat while cycle
5. SprintfBox(INFORMATION, "ListCurrentString 1",
ListCurrentString now is: "1.2"
szProgressiveString now is: "1.1" <--???
...
then ListCurrentString traverse all the list but szProgressiveString still remain on the first element blocking the execution (I had to oper Task Manager to end the process...)
Posted 19 November 2004 - 18:47
When an item is deleted from the list, the list index is no longer correct.
After you delete an item in the list, your next executable instruction is:
ListCurrentString (listCT, szCurrentString);
You need to use:
ListSetIndex(listCT, LISTFIRST );
ListGetFirstString ( listCT, szProgressive );
This command will reset the list index, and effectively make you restart from the new 1st index. The script will only drop through to the end of the list when all the selected strings that meet your criteria are removed.
After you delete an item in the list, your next executable instruction is:
ListCurrentString (listCT, szCurrentString);
You need to use:
ListSetIndex(listCT, LISTFIRST );
ListGetFirstString ( listCT, szProgressive );
This command will reset the list index, and effectively make you restart from the new 1st index. The script will only drop through to the end of the list when all the selected strings that meet your criteria are removed.
CODE |
nProgressive = ListGetFirstString ( listCT, szProgressive ); while nProgressive != END_OF_LIST if (StrLengthChars (szProgressive) < 4) then // string is too short ListDeleteString(listCT); // remove list entry ListSetIndex(listCT, LISTFIRST ); // reset index - important nProgressive = ListGetFirstString ( listCT, szProgressive ); // new 1st index else nProgressive = ListGetNextString (listCT, szProgressive ); endif; endwhile; |
Hope this helps.
Edited by Ozone, 19 November 2004 - 18:56.