[futurebasic] Re: [FB] February Challenge: UCASE$

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : February 2001 : Group Archive : Group : All Groups

From: Alain Pastor <apastor@...>
Date: Tue, 06 Feb 2001 13:07:31 +0100

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
-----------------------------------------------------