Heather Donahue wrote: > At 9:03 PM +1300 on 2/5/01, Robert Purves wrote: > > >Here's this month's challenge. As a change from the usual code-bashing > >parties, this one is intended to exercise your detective skills, not > >programming ability. > > > >Step 1. Run this program in FB^3: > > > >'----------------------- > >window 1 > >if ( ucase$( "`" ) = "a" ) then print "That's a weird challenge!" > >do > >handleevents > >until fn Button > >'----------------------- > > >Step 2. Explain why the program behaves as it does, indicating with whom > >should lie the responsibility (or blame) for the anomaly. > > The UCASE routine calls a ToolBox function 'UpperString' and it is > responsible. It isn't intended to simply compare A-Z [a-z] strings, > it is to compare strings the way the Mac file system does. It deals > with characters in the range 0x00 to 0xD8, dec 0 to 216 I've found however that the Toolbox call is strangely implemented (if I'm not going south). In the Subs Compiler include file we can read this "fn uprString(gFBStr&.FBStrAcc$)". Actually uprString is a procedure that accepts a second parameter to deal with diacritics, so I'm wondering where it has gone. I cannot write this for instance: CALL UprString(myString,_false). I have already investigated the UprString call with FBII, and I discovered that the call failed on some diacritics especially if you set diacsens (the second parameter) to true. > > > >Step 3. [optional extra credit] Explain why there is no anomaly when the > >program is run in FBII. > > I would assume that it doesn't access FN UpperString, there isn't any > 68k inline code for that function. I'm not sure how FBII does it but > a simple (non doublebyte) method was always to subtract 32 from the > ASCII value of the lowercase to get the uppercase for a-z > > By the way, I didn't actually know any of this until about 10 minutes > ago, well except for the old UCASE method. > FBII didn't use any Toolbox call to perform the uppercasing (it obviously didn't take into account foreign languages). I guess that Andy built a function that did something like this: LOCAL MODE DIM count LOCAL FN UCASE$(theStr as str255) FOR count = 1 TO theStr[0] LONG IF theStr[count] < = _"z" LONG IF theStr[count] > = _"a" theStr[count] -= _" " END IF END IF NEXT END FN = theStr All the characters falling outside a given range are ignored. You would obtain true doing this in FBII: if ( ucase$( "`" ) = "`" ), therefore "`" == "a" will never be true in your example. Unfortunately, for us (French and others) this would give the same result with: if ( ucase$( "é" ) = "é" ) and the like. I suspect this is the way that was used by all the old BASICs (and perhaps new ones too in order to maintain code compatibility). Perhaps the UprString FB built in the Compiler is a patch made by Andy for the same compatibility issue forcing the UprString Toobox call to be called with diacsens set to false which is more reliable in that regard than true, but not totally. I think that the piece of code you've posted for that challenge would work probably correctly in every case if we do the following change in the Compiler include file for the UCASE$ function: UpperCaseText(@gFBStr&.FBStrAcc$+1,|@gFBStr&.FBStrAcc$|,_smCurrentScript) Between the old built-in function, the UprString and the UpperCaseText Toolbox calls I personally would have chosen the latter. Now, perhaps you've got an idea on the reason why UprString is an FN instead of a CALL? Darn!! I have had just a look at the thing, and I'm slightly wrong on those explanations: First I was intrigued by Heather's reply because she used the word UpperString instead of UprString. So I typed it in the Editor and performed a command-E, and here is the surprise: UprString is built as an FN made to call UpperString (which is correctly implemented). FN UprString calls UpperString with diacsens set to _zTrue and not to _false as I would have expected it. This setting is better for us because it gives, unlike FBII, UCASE$("é") = "É", but it is less compatible than setting diacsens to false which gives UCASE$("é") = "E" Now, the question is: why UprString is implemented that way? I see no reason why the Toolbox call has been implemented differently from the Apple way. UprString was not recognized by FBII therefore it couldn't be a compatibility problem between FBII and FB^3. Why the Runtime doesn't use a private function (say something like fn myUprString) to preprocess the actual call (UpperString), leaving in place the UprString call defined by Apple? I don't know. -- Cheers Alain ----------------------------------------------------- FB^3 in Europe: http://euro.futurebasic.com/ FB II Pouch: http://www.pixmix.com/FB/outils.html -----------------------------------------------------