WinBatch® Technical Support Forum

All Things WinBatch => WinBatch => Topic started by: bottomleypotts on August 04, 2019, 06:48:52 AM

Title: MapKeyExist error??
Post by: bottomleypotts on August 04, 2019, 06:48:52 AM
I'm having an issue with MapKeyExist.

From my debugtrace:

z=zFiles[FileKey]
(78) VALUE STRING => "3C13E7A0-D889B378-9D732B77-3FC10261"

If MapKeyExist(zFiles,FileKey)==@FALSE
(94) IF DO==>TRUE


The key clearly exists but when I test it it fails. The map is being created correctly. Other maps in the same app work. Help!
Title: Re: MapKeyExist error??
Post by: td on August 04, 2019, 07:13:37 AM
Without knowing exactly what the contents of the FileKey variable in both cases it is impossible to offer any assistance.
Title: Re: MapKeyExist error??
Post by: bottomleypotts on August 04, 2019, 09:24:33 AM
These two lines follow one another in the app. The first statement is there just to show that there is actually data in the array.

The FileKey is just the full path/filename of a file - eg. "C:\config.sys".
Title: Re: MapKeyExist error??
Post by: kdmoyers on August 05, 2019, 06:23:09 AM
From my considerable experience with tracking down winbatch problems, I can advise that the most direct route to a solution is a ten line program that demonstrates the problem.  So, could you maybe rig up a little program that demonstrates the problem?  It might take time to create, but it greatly increases chances of a solution.

$0.02
-Kirby
Title: Re: MapKeyExist error??
Post by: td on August 05, 2019, 07:02:19 AM
Good point.  Consider the following:

Code (winbatch) Select
FileKey = 'C:\config.sys'
zFiles[FileKey] = "3C13E7A0-D889B378-9D732B77-3FC10261"
z=zFiles[FileKey]
bExist = MapKeyExist(zFiles,FileKey)
; bExist is set to 1 as expected.


In the above example, bExist is set to 1 which indicates that the key does exist in the associative array.  That is why the exact contents of the variable in both lines are important and an example that reproduces the problem is needed.
Title: Re: MapKeyExist error??
Post by: chrislegarth on August 05, 2019, 01:38:13 PM
This forum is the best...how have I survived without the Map functions?!?!  Oh, I know, by using two separate delimited variables and trying to keep them aligned.
The MAP is WAY better!  Thanks for bringing this function to my attention!  How many years have I not know of this???  :o

Thank You!
Title: Re: MapKeyExist error??
Post by: td on August 05, 2019, 03:01:13 PM
The map functions first appeared in version 2019a.  You can always find out what's new here: https://www.winbatch.com/whatsnew.html (https://www.winbatch.com/whatsnew.html)
Title: Re: MapKeyExist error??
Post by: td on August 07, 2019, 09:42:27 AM
Since the OP has not reported back we decided to create a new test for the MapExist function.  The test generates a WIL map of 20,000 elements.  The element keys range in a randomly determined length of 1 to 255 characters.  The key's contents were randomly determined as well.  For this test 1000 of the keys are randomly selected for lookup by first using array syntax to obtain the key's value and then calling the MapExist function. The two lookups are on consecutive lines to attempt to duplicates the OP's conditions.  We ran the test 4 times with a new data set each time.  The MapExist function never failed to find a key.   

Until we receive new information, the OP's problem will have to remain a mystery.
Title: Re: MapKeyExist error??
Post by: bottomleypotts on August 15, 2019, 10:43:23 PM
Sorry for not getting back to the forum. Have been busy with work.

My app reads a file that is @TAB delimited map. If the file does not exist then a blank map is created.

The app has 2 maps, one works the other does not.

After modifying the map it writes it to a @TAB delimited file. That is the map read in the beginning.
Title: Re: MapKeyExist error??
Post by: td on August 16, 2019, 06:58:12 AM
Again, as Kirby suggested, you will have to provide a small sample script that reproduces the problem.  Your descript does really convey anything that is "actionable."
Title: Re: MapKeyExist error??
Post by: stanl on August 16, 2019, 07:22:18 AM
Quote from: td on August 16, 2019, 06:58:12 AM
Again, as Kirby suggested, you will have to provide a small sample script that reproduces the problem.  Your descript does really convey anything that is "actionable."


Agreed. And if all the OP is doing is reading tab-delimited and re-writing tab-delimited there are numerous other ways to accomplish.
Title: Re: MapKeyExist error??
Post by: bottomleypotts on August 16, 2019, 10:21:16 AM
The app checksums files. That's it!

There is a bug somewhere. I provided 2 lines of a debugtrace.

The app has been re-written using a database so I can't provide the source code that caused the error.
Title: Re: MapKeyExist error??
Post by: td on August 16, 2019, 01:19:09 PM
Quote from: bottomleypotts on August 16, 2019, 10:21:16 AM
The app checksums files. That's it!

OK?

Quote
There is a bug somewhere. I provided 2 lines of a debugtrace.

The DebugTrace file really doesn't help because it is just a cut&paste that doesn't provide any context.  As was mentioned several posts back, we have made many different attempts to reproduce your problem as described without success. 

Quote
The app has been re-written using a database so I can't provide the source code that caused the error.

No one was asking for an "app". Just a simple example the demonstrates the problem.  We can't fix what we can't recreate... 
Title: Re: MapKeyExist error??
Post by: stanl on August 17, 2019, 06:20:43 AM
Quote from: bottomleypotts on August 16, 2019, 10:21:16 AM
The app has been re-written using a database so I can't provide the source code that caused the error.


If a database is involved might one assume the use of WB 'mapping' is related to either data that is in the db or data that is going to be placed in or associated with existing data in the db.


Haven't worked with map values that much but is it possible a NULL value could be producing the error?
Title: Re: MapKeyExist error??
Post by: td on August 19, 2019, 07:49:51 AM
No, a NULL value could not produce the error.

The only way we have found to produce the behavior descript by the OP is to do something like the following:

Code (winbatch) Select
key = '1'
map[key] = 'abc'
ErrorMode(@Off)
value = map[key]
bTest = MapKeyExist(map, key)


The reason the above produces behavior like that described by the OP is that the line map[key] = 'abc' doesn't create a WIL map.  It creates a regular WIL array and the ErrorMode(@Off) line suppress the error generated by MapKeyExist.   

There are several ways to avoid the above problem.  You can create an empty map before assigning any values to the map.  For example,

Code (winbatch) Select
map = MapCreate()
map['1'] = 'abc'
bTest = MapKeyExist(map, '1')


correctly creates a WIL map that contains the key value "1".

Another way to prevent the problem is to make sure the key that creates the map cannot be converted to a number.  For example,

Code (winbatch) Select
map['not all digits'] = 'abc'
bTest = MapKeyExist(map, 'not all digits')


This behavior is also covered in the Consolidated WIL Help file.
Title: Re: MapKeyExist error??
Post by: bottomleypotts on August 22, 2019, 12:18:22 AM
Code (winbatch) Select

BoxOpen(`Example`,``)

zFilesFN=DirScript():`Files.txt`
zKeysFN=DirScript():`Keys.txt`

If FileExist(zFilesFN)
    mFiles=MapFileGetCsv(zFilesFN,@TAB)
Else
    mFiles=MapCreate()
EndIf
If FileExist(zKeysFN)
    mKeys=MapFileGetCsv(zKeysFN,@TAB)
Else
    mKeys=MapCreate()
EndIf

zFolder=`C:\Windows\`
lFiles=``

If DirExist(zFolder)
    BoxText(`Getting list of Files ...`)

    lFiles=FileItemize(zFolder:`*.*`)
    If lFiles!=``
        For x=1 to ItemCount(lFiles,@TAB)
            zFile=ItemExtract(x,lFiles,@TAB)

            zFullName=zFolder:zFile

            zFileInfos=FileInfoToArray(zFullName,1|2)

            zFileSize=zFileInfos[1,1]
            zModifiedDate=StrReplace(zFileInfos[1,2],`:`,``)
            zCreatedDate=StrReplace(zFileInfos[1,4],`:`,``)

            zFile=zFullName:`\`:zFileSize:`\`:zModifiedDate:`\`:zCreatedDate

            If MapKeyExist(mFiles,zFile)
                BoxText(zFile:@CR:`Map exists`)
            Else
ErrorMode(@OFF)
                Message(``,mFiles[zFile])
ErrorMode(@CANCEL)
                zDigest=FileDigest(zFullName,`MD5`,1)
                mFiles[zFile]=zDigest

                If MapKeyExist(mKeys,zDigest)
                    BoxText(zFile:@CR:`Map not exists`:@CR:`Map exists`)
                Else
                    BoxText(zFile:@CR:`Map not exists`:@CR:`Map not exists`)

                    mKeys[zDigest]=zFile
                EndIf
            EndIf
        Next x
    EndIf
EndIf

Rc=MapFilePutCsv(zFilesFN,mFiles,@TAB)
Rc=MapFilePutCsv(zKeysFN,mKeys,@TAB)


This gives me the error.
Title: Re: MapKeyExist error??
Post by: td on August 22, 2019, 10:05:52 AM
It appears the OP completely changed the original post.  That might cause some confusion to future readers but no matter.

The problem has been found.  The MapKeyExist function only accepts an ANSI string as a key parameter.  However, the FileItemize function return type is Unicode. This means that the string returned by ItemExtract is also Unicode.   The WIL interpreter dutifully converts the key variable ("zFile" in the above example) from Unicode to ANSI before passing it to the MapKeyExist function.  However, the interpreter also retains the Unicode identity of the variable.  The MapKeyExist function logic detects this dual identity and reports that the key cannot possibly exist because only ANSI only strings can be keys in an associative array. 

The fix is a very simple one and will appear in the next release.

Many thanks to the OP for providing a working example that we could use to find the problem.
Title: Re: MapKeyExist error??
Post by: td on August 22, 2019, 01:50:25 PM
It would be negligent to not offer a simple one-line workaround until the next release.

Code (winbatch) Select
strKey      = 'key'
strPair     = 'key,value'

; Unicode version of key.
strwKey     = ChrStringToUnicode(strKey)

; Test map
aMap = MapCreate(strPair)

; The workaround -> force Unicode to ANSI string conversion.
strLook = ChrUnicodeToString(strwKey)

; Now the test.
bResult =  MapKeyExist(aMap, strLook)
if bResult then Message('Map Workaround', 'Works!!')
else Message('Map Workaround', 'Is a miserable failure!!')