gm2
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Inconsistent HIGH values with 'ARRAY OF CHAR'


From: Gaius Mulley
Subject: Re: Inconsistent HIGH values with 'ARRAY OF CHAR'
Date: Wed, 10 May 2023 14:27:24 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)

Rudolf Schubert <rudolf@muc.de> writes:

> Hi Gaius,
>
> I'm still hunting miscellaneous bugs which occurred with my 'big squash file'.
>
> One thing I noted today is:
>
> the HIGH values seen inside a PROCEDURE do not reflect the expectations.
>
> Again, I've written a small example program which shows the problem:
>
>
> MODULE port_test8_gm2;
>
> FROM IOChan IMPORT
>   ChanId;
> FROM StdChans IMPORT
>   StdOutChan;
> FROM Strings IMPORT
>   Length;
> FROM TextIO IMPORT
>   WriteLn, WriteString;
> FROM WholeIO IMPORT
>   WriteCard;
>
>
> VAR
>   str_a:                        ARRAY[0..0] OF CHAR;
>   str_b:                        ARRAY[0..1] OF CHAR;
>   str_c:                        ARRAY[0..2] OF CHAR;
>
>
> PROCEDURE ShowStringInfos(the_str: ARRAY OF CHAR);
>   VAR
>     cid_out:                    ChanId;
>
>   BEGIN                         (* PROCEDURE ShowStringInfos *)
>     cid_out:=StdOutChan();
>
>     WriteString(cid_out, 'Length(the_str): ');
>     WriteCard(cid_out, Length(the_str), 1);
>     WriteLn(cid_out);
>
>     WriteString(cid_out, 'HIGH(the_str): ');
>     WriteCard(cid_out, HIGH(the_str), 1);
>     WriteLn(cid_out);
>
>     WriteString(cid_out, 'the_str: ');
>     WriteString(cid_out, the_str);
>     WriteLn(cid_out);
>
>     WriteLn(cid_out);
>   END ShowStringInfos;
>
>
> BEGIN                           (* MODULE port_test8_gm2 *)
>   ShowStringInfos('1');
>   ShowStringInfos('12');
>   ShowStringInfos('123');
>
>   str_a:='a';
>   ShowStringInfos(str_a);
>   str_b:='ab';
>   ShowStringInfos(str_b);
>   str_c:='abc';
>   ShowStringInfos(str_c);
>
>   str_c:='d';
>   ShowStringInfos(str_c);
> END port_test8_gm2.
>
>
> ShowStringInfos just prints out the Length, the HIGH value and the
> string proper which is passed to the PROCEDURE. When using literals
> '1', '12' and '123' the HIGH values are 0, 2 and 3. So I guess either
> for '1' the HIGH value should be 1 and not 0 or for '12' and '123'
> the HIGH values should be 1 and 2 and not 2 and 3. I can only compare
> with GPM and there they report a HIGH value of 1 for '1' (and 2 and 3
> for '12' and '123'). So the question is what will be the correct behaviour?
>
>
> BR
>
> Rudolf

Hi Rudolf,

[As an aside I've checked various reference texts and I'm still to find
 the correct behaviour :-).
 As far as can tell PIM[234] and ISO is silent on the matter.] 

Interesting, given the last accessible char in a string is defined as

  HIGH (a) = i or a[i] = 0C

so I think the behaviour in the test code above is logically correct,
but it is certainly looks inconsistant :-).

However it appears that gm2 does not append a 0C to a string when it
passes a single char literal as an actual parameter to an open array.  I
suspect it makes sense to change the actual parameter '1' to deliver a
HIGH value of 1 (and add a 0C terminator).  This would seem more
consistant as the single char literal is now viewed as a string.  (I
remind myself that a single char variable cannot be passed to an open
array).

For example here is some test code:

MODULE hightests ;


FROM libc IMPORT printf, exit ;
FROM StrLib IMPORT StrCopy ;

PROCEDURE testhigh (a: ARRAY OF CHAR; expected: CARDINAL; first: CHAR; 
checkNul: BOOLEAN) ;
VAR
   copy: ARRAY [0..10] OF CHAR ;
BEGIN
   StrCopy (a, copy) ;
   IF HIGH (a) # expected
   THEN
      printf ("unexpected high value, HIGH(%s) should be %d but was passed 
%d\n",
              copy, expected, HIGH (a)) ;
      code := 1
   END ;
   IF a[0] # first
   THEN
      printf ("unexpected first value in open array, %s, a[0] should be %c but 
was passed %c\n",
              a, first, a[0]) ;
      code := 2
   END ;
   IF checkNul AND (a[HIGH(a)] # 0C)
   THEN
      printf ("expected the array to contain a 0C terminator\n") ;
      code := 3
   END
END testhigh ;


VAR
   str0: ARRAY [0..0] OF CHAR ;
   str1: ARRAY [0..1] OF CHAR ;
   str2: ARRAY [0..2] OF CHAR ;
   str3: ARRAY [0..3] OF CHAR ;
   ch  : CHAR ;
   code: INTEGER ;
BEGIN
   str0 := '_' ;
   str1 := '_1' ;
   str2 := '_2' ;
   str3 := '_3' ;
   code := 0 ;
   testhigh ('', 0, 0C, TRUE) ;
   testhigh ('1', 1, '1', FALSE) ;
   testhigh ('12', 2, '1', TRUE) ;
   testhigh ('123', 3, '1', TRUE) ;
   testhigh ('1234', 4, '1', TRUE) ;
   testhigh (str0, 0, '_', FALSE) ;
   testhigh (str1, 1, '_', FALSE) ;
   testhigh (str2, 2, '_', TRUE) ;
   testhigh (str3, 3, '_', TRUE) ;
   IF code = 0
   THEN
      printf ("all tests pass\n")
   ELSE
      exit (1)
   END
END hightests.


regards,
Gaius



reply via email to

[Prev in Thread] Current Thread [Next in Thread]