[comp.os.vms] Pascal strings

pfister_rob@rangly.dec.com (full moon today) (05/02/88)

> decwrl!labrea!rutgers!elbereth.rutgers.edu!elkins writes
 
>Is there a way in VAX Pascal to define a procedure that will take
>a variable length quoted string as a parameter?  

>Example of what I want to do:
 
>     foo('This is a string of any length');  {User-written procedure foo}
 
>Examples of what I am avoiding:
 
>     foo(PackedArrayName, StringLength);  {Packed array and string length}
> or
>     foo(String.Body, String.Length);  {Record with packed array and integer}
 
What I do is...

TYPE 
    STRING=VARYING[255] OF CHAR;
.
.
.
VAR
   bar:STRING:='blah blah blah';

PROCEDURE foo(line:STRING);
.
.
.
  v=LENGTH(line);  (* if I wanna know the length of the string...*)
.
.
.

Is this what you mean?

Disclaimer:  This posting was generated by random line noise, not by official
             consenus of my employer...

|Robert Pfister           Digital Equipment Corp
|Email: Pfister_Rob%Dneast.dec@decwrl.dec.com   

cfchiesa@bsu-cs.UUCP (Christopher Chiesa) (05/03/88)

In article <8805021136.AA05274@decwrl.dec.com>, pfister_rob@rangly.dec.com (full moon today) writes:
> > decwrl!labrea!rutgers!elbereth.rutgers.edu!elkins writes
>  
> >Is there a way in VAX Pascal to define a procedure that will take
> >a variable length quoted string as a parameter?  
> 
   [examples of goal, avoided methods, and solution deleted; you've all 
    probably seen it five times by now...  besides there's that line counter]

> TYPE 
>     STRING=VARYING[255] OF CHAR;
> .
> .
> .
> VAR
>    bar:STRING:='blah blah blah';
> 
> PROCEDURE foo(line:STRING);
> .
> .
> .
>   v=LENGTH(line);  (* if I wanna know the length of the string...*)
> .
> .
> .
> 
> Is this what you mean?

I just wanted to point out that in this context, the Vax Pascal LENGTH function
does NOT return the contents of the varying_string ".length" field.  It returns
the DECLARED SIZE of the particular variable, in this case the value 255, re-
gardless of the number of "valid characters" actually in the string.






[line counters must die]









-- 
UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!cfchiesa 
cfchiesa@bsu-cs.UUCP                                           

robert@arizona.edu (Robert J. Drabek) (05/03/88)

In article <2834@bsu-cs.UUCP>, cfchiesa@bsu-cs.UUCP (Christopher Chiesa) writes:
: In article <8805021136.AA05274@decwrl.dec.com>, pfister_rob@rangly.dec.com (full moon today) writes:
: 
: > TYPE 
: >     STRING=VARYING[255] OF CHAR;
: > VAR
: >    bar:STRING:='blah blah blah';
: > PROCEDURE foo(line:STRING);
: > .
: >   v := LENGTH(line);  (* if I wanna know the length of the string...*)
: 
: I just wanted to point out that in this context, the Vax Pascal LENGTH function
: does NOT return the contents of the varying_string ".length" field.  It returns
: the DECLARED SIZE of the particular variable, in this case the value 255, re-
: gardless of the number of "valid characters" actually in the string.
: 


Why don't I see this?  I've used this fairly often and it seems I always
came up with the number of valid characters.




-- 
Robert J. Drabek
Department of Computer Science
University of Arizona
Tucson, AZ  85721

cfchiesa@bsu-cs.UUCP (Christopher Chiesa) (05/05/88)

In article <5302@megaron.arizona.edu>, robert@arizona.edu (Robert J. Drabek) writes:
> In article <2834@bsu-cs.UUCP>, cfchiesa@bsu-cs.UUCP (Christopher Chiesa) writes:

> : I just wanted to point out that in this context, the Vax Pascal LENGTH 
> : function does NOT return the contents of the varying_string ".length" field.
> : It returns the DECLARED SIZE of the particular variable, in this case the 
> : value 255, regardless of the number of "valid characters" actually in the 
> : string.
> 
> 
> Why don't I see this?  I've used this fairly often and it seems I always
> came up with the number of valid characters.

That's a VERY GOOD question!  Perhaps we have different versions or releases
of Vax Pascal?  Although I would think the operation of the LENGTH function 
would not change...

All I can say is that I *always* have to write my OWN "string length" function
when I want to work with type VARYING OF CHAR in Vax Pascal...

C.Chiesa
-- 
UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!cfchiesa 
cfchiesa@bsu-cs.UUCP                                           

hjm@cernvax.UUCP (hjm) (05/05/88)

Hi guys,

     Two minutes inside a big friendly orange manual (PASCAL User's Guide)
showed me the *real* way to do this.  Neat, huh!  No blurb, just code ...

==============================================================================
program foo(input, output);

procedure wr( s : [class_s] packed array [a..b : integer] of char);
begin
  writeln('"',s,'" starts at ',a:1,' and goes to ',b:1)
end;

begin
  wr('Hello world!')
end.
==============================================================================

gives the expected response:

"Hello world!" starts at 1 and goes to 12

I hope that solves everyone's problems on VAX PASCAL strings (PASCAL V3.5)

	Hubert Matthews
	CERN
	1211 Geneva 23
	Switzerland

"Please note that the code expressed here is entirely MY code and does not
reflect the code of my employer"

robert@arizona.edu (Robert J. Drabek) (05/06/88)

In article <2864@bsu-cs.UUCP>, cfchiesa@bsu-cs.UUCP (Christopher Chiesa) writes:
> 
> That's a VERY GOOD question!  Perhaps we have different versions or releases
> of Vax Pascal?  Although I would think the operation of the LENGTH function 
> would not change...
> All I can say is that I *always* have to write my OWN "string length" function
> when I want to work with type VARYING OF CHAR in Vax Pascal...

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
I tried the following under version 3.6 of VMS Pascal.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

program s(input, output);

type string = varying[36] of char;

procedure stest(str : string);
begin

  writeln(output, 'The string is  <', str, '>' );
  writeln(output, '  its length is ', length(str):1)

end;  { stest }

var s1 : string;

begin { main }

  stest('Hello');    { a literal test }

  s1 := 'Good bye';  { a variable test }
  stest(s1)

end.  { main }

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The output was:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The string is  <Hello>
  its length is 5
The string is  <Good bye>
  its length is 8

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-- 
Robert J. Drabek
Department of Computer Science
University of Arizona
Tucson, AZ  85721

jonathan@ucsvc.unimelb.edu.au (05/06/88)

In article <Apr.29.15.09.31.1988.23840@elbereth.rutgers.edu>,
 elkins@elbereth.rutgers.edu (George Elkins) writes:

> Is there a way in VAX Pascal to define a procedure that will take
> a variable length quoted string as a parameter? ... etc. ...
> ...
> Example of what I want to do:
>      foo('This is a string of any length');  {User-written procedure foo}
> 
> George Elkins

Various postings have been sent in response to this original query and
in response to some of those followups.  I may have missed something along
the way, but it seems to me that the original question has not been
satisfactorily answered so far.  Herein, my attempt to do so - some information
from previous postings may be repeated here for completeness.  [This posting
is rather long.]

"Pascal" here refers to VAX Pascal version 3.5 running on VAX/VMS version 4.7:

Pascal has two string types: 
- fixed length:   e.g. PACKED ARRAY [1..50] OF CHAR ;
- varying length: e.g. VARYING [50] OF CHAR ;

Other arrays of characters can be declared but they are *not* treated as
strings (e.g. ARRAY [1..50] OF CHAR).

The varying length string is effectively a two-field record.  For the example
above, the record declaration would be like this:

  RECORD
    LENGTH : [WORD] 0..50 ;
    BODY   : PACKED ARRAY [1..50] OF CHAR ;
  END ;

Pascal has a number of ways to pass arrays and strings as parameters to
procedures and functions.  In order to answer the original question, the
following method is the simplest implementation to use.  Pascal generally
calls this method "Conformant Schema".

To declare a procedure to accept a FIXED-length READONLY string, the following
syntax may be used:

  PROCEDURE  POSSUM (String_Param : PACKED ARRAY [Low..High:INTEGER] OF CHAR) ;

A variable declared as PACKED ARRAY OF CHAR of **ANY** valid length may be
passed to such a procedure.  Also, any non-zero length quoted string may be
passed directly to such a procedure.  The identifiers "Low" and "High" are
implicitly declared bound identifiers and represent the lower and upper bounds
respectively of the conformant array's indices.  In the case of a quoted string,
"High" in this example would contain a value equal to the length of the string
passed.  (Aside: "Low" and "High" may be any valid identifiers).

Valid invocations of POSSUM would be of the form:
POSSUM (Packed_String_Var) ;  POSSUM ('My dog has fleas.') ;

To declare a procedure to accept a VARYING-length READONLY string, the following
syntax may be used:

  PROCEDURE  WOMBAT (String_Param : VARYING [Len] OF CHAR) ;

A variable declared as VARYING OF CHAR of **ANY** valid length may be
passed to such a procedure.  Also, any quoted string (even zero-length) may be
passed directly to such a procedure.  The identifier "Len" is an implicitly
declared INTEGER which, in the case of a READONLY parameter, will contain the
*actual* length of the string passed (NOT the maximum declared length).
For a quoted string, "Len" in the example above provides the length
of the string passed.  (Aside: "Len" may be any valid identifier).

[NOTE: If the formal parameter is declared as a *READWRITE* VARYING OF CHAR,
the "Len" identifier will contain the MAXIMUM declared length of the *variable*
passed.]

Valid invocations of WOMBAT would be of the form:
WOMBAT (Varying_String_Var) ;  WOMBAT ('My cat has ferrets.') ;

The length of string variables may be obtained in one of the following ways:

For PACKED ARRAY OF CHAR, VARYING OF CHAR, and quoted strings, the
function LENGTH (String) will return the *current* length of the string value.

For VARYING OF CHAR, the pre-declared field LENGTH will return the *current*
length of the VARYING array (e.g. My_Varying_String.LENGTH).

When passing string parameters by descriptor to VAX/VMS Run-Time Library
routines, the following conventions may normally be observed:

To pass a READONLY string of *ANY* type, declare the *formal* parameter in the
RTL routine declaration as a CLASS_S descriptor; 
   e.g.  Any_String : [CLASS_S] PACKED ARRAY [Lo..Hi:INTEGER] OF CHAR ;

To pass a READWRITE string of type PACKED ARRAY OF CHAR, use the %STDESCR
mechanism, either on the actual parameter when passed, or on the formal
parameter of the RTL routine declaration;
   e.g. { formal declaration } %STDESCR Packed_String : PACKED ARRAY ..... ;
        { actual parameter }   LIB$GET_COMMON (%STDESCR Return_String) ;

To pass a READWRITE string of type VARYING OF CHAR, use the %DESCR mechanism,
either on the actual parameter when passed, or on the formal parameter of the
RTL routine declaration;
   e.g. { formal declaration } %DESCR Varying_String : VARYING ..... ;
        { actual parameter }   LIB$GET_COMMON (%DESCR Return_String) ;

Much of this information is available in the on-line HELP.
All of it is available in the DEC publications "VAX PASCAL Reference Manual"
and "VAX PASCAL User Manual".

Hope all this clarifies and helps.

-------------------------------------------------------------------------------
Sender:        Jonathan Ridler
Organization:  The University of Melbourne. (University Computing Services)
ACSnet,CSNET:  jonathan@ucsvc.dn.mu.oz
INTERNET:      jonathan%ucsvc.dn.mu.oz@uunet.uu.net
UUCP: {uunet,ubc-vision,nttlab,mcvax,ukc}!munnari!ucsvc.dn.mu.oz.au!jonathan
-------------------------------------------------------------------------------

cfchiesa@bsu-cs.UUCP (Christopher Chiesa) (05/07/88)

In article <2864@bsu-cs.UUCP>, I wrote: 
> In article <5302@megaron.arizona.edu>, robert@arizona.edu (Robert J. Drabek) writes:
> > In article <2834@bsu-cs.UUCP>, cfchiesa@bsu-cs.UUCP (Christopher Chiesa) writes:
> 
> > : I just wanted to point out that in this context, the Vax Pascal LENGTH 
> > : function does NOT return the contents of the varying_string ".length" field.
> > : It returns the DECLARED SIZE of the particular variable, in this case the 
> > : value 255, regardless of the number of "valid characters" actually in the 
> > : string.
> > 
> > 
> > Why don't I see this?  I've used this fairly often and it seems I always
> > came up with the number of valid characters.
> 
> That's a VERY GOOD question!  Perhaps we have different versions or releases

Well.  I stand chagrined.  Several other people and myself have tried the LENGTH
function within the last few days, and it does indeed seem to give the desired
results.  Thinking back, I guess the problem *I* had with it, was that it DOES
NOT IGNORE TRAILING BLANKS when one reads blank-filled records from a file, and
my memory of writing MY OWN "LENGTH" FUNCTION, had to do with counting only 
the "valid" characters in the string, disregarding trailing blanks.

My apologies for cluttering up the net with a mistaken statement/posting.  Glad
you people are on the ball!  :-)

Chris Chiesa
 
-- 
UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!cfchiesa 
cfchiesa@bsu-cs.UUCP                                           

ijah400%ivax.DECnet@GOLD.BACS.INDIANA.EDU ("IVAX::IJAH400") (07/09/88)

In article <2864@bsu-cs.UUCP>, cfchiesa@bsu-cs.UUCP (Christopher Chiesa) writes:
>
> That's a VERY GOOD question!  Perhaps we have different versions or releases
> of Vax Pascal?  Although I would think the operation of the LENGTH function
> would not change...
> All I can say is that I *always* have to write my OWN "string length" function
> when I want to work with type VARYING OF CHAR in Vax Pascal...

For:

module my_length;

[global] function my_length (var str : varying[u1] of char): integer;
begin
  my_length := length(str)
end { my_length };

end { module }.

Pascal version 3.5-196 generates the following code (comments mine):

        .TITLE  MY_LENGTH
        .IDENT  \01\

	.PSECT  $CODE,PIC,CON,REL,LCL,SHR,EXE,RD,NOWRT,2

	.ENTRY  MY_LENGTH,^M<>	; 0003
	SUBL2   #8,SP		; Make room for a temp string descriptor
	MOVQ    @4(AP),-8(FP)	; Copy the string descriptor to the temp
1$:     MOVL    -4(FP),AP	; 0005 Pick up address of length word
	MOVZWL  (AP),AP		; Get contents (this is *current* length)
	MOVL    AP,R0		; 0006 Return it as the function value.
	RET

Definitely appears to be the *current* length of the string to me.  I
wouldn't be surprised if older versions of the Pascal were wrong though;
I've seen other bugs in VMS related to (Digital) programmer confusion
about how to get the current length of a varying-length string.

	James Harvey
	IJAH400@INDYVAX (BITNET) or IJAH400%IVAX.DECNET@GOLD.BACS.INDIANA.EDU