comp.lang.ada
 help / color / mirror / Atom feed
* Re: How to assign STRINGs?
@ 1993-08-26 14:09 Joe Hildebrand
  0 siblings, 0 replies; 8+ messages in thread
From: Joe Hildebrand @ 1993-08-26 14:09 UTC (permalink / raw)


>> On 25 Aug 93 21:42:26 GMT, alex@cs.umd.edu (Alex Blakemore) said:
In article <25gmc2$3cf@neomimsy.cs.umd.edu> alex@cs.umd.edu (Alex Blakemore) wr
ites:


   Alex> In article <1993Aug25.121754.20413@hellgate.utah.edu>
   Alex> matwood%peruvian.cs.utah.edu@cs.utah.edu (Mark Atwood)
   Alex> writes:
   >> how DO i assign the results of a function returning an
   >> unconstrained string to a constrained string?

   Alex> in Ada83, you have two good choices (and one sort of kludgy
   Alex> one)

   Alex> a. initialize a constant string with the function result
   Alex> cmdline : constant string := dos.get_parms;

   Alex> b. pass the function result as an in parameter to another
   Alex> subprogram text_io.put_line (dos.get_parms);

   Alex> or [worst of all]

   Alex> c. get the bounds first, declare the variable, call the
   Alex> function

   Alex> declare cmdline : string (dos.first_parm_number
   Alex> .. dos.last_parm_number); begin cmdline := dos.get_parms;
   Alex> end;

   Alex> -- this is brittle, esp if you ever add concurrency

We created a simple function that combines b. and c.


NOTE: I don't claim this is pretty, but it seems to work.  It needs
some cleaning up, since this is one one the first functions we wrote
when we were learning Ada.  In particular, Out_Str should only be an
out parameter.  PAR_STR_Length returns the number of "useful"
characters in a string by subtracting the number of trailing spaces
and ascii.nul's.


procedure PAR_STR_copy( Out_str   : in out string;
                        In_Str    : in     string;
                        Pad_Char  : in     character := ' ' ) is 

     In_str_len	 : integer := 0;
     Out_str_len : integer := 0;
     Low_Char    : integer := 0;
     Num_Chars   : integer := 0;

begin

--	Get the length of the string to be copied

   In_Str_Len := PAR_STR_length( In_Str );

--	Obtain the size of the target string

   Out_Str_Len := Out_Str'last - Out_Str'first + 1;

--	Find the first character position in the In_Str to be copied.
--	This is in case the In_Str is passed in as a string slice.

   Low_Char := In_Str'first;

--	Only copy In_Str_Len number of characters

   Num_Chars := In_Str_Len;

--	Make sure we only copy the number of characters the target
--	string can hold.

   if ( Num_Chars > Out_Str_Len ) then
      Num_Chars := Out_Str_Len;
   end if;

--	Copy the string.

   Out_Str( Out_Str'first..(Out_Str'first+Num_Chars-1)) := 
                             In_Str(Low_Char..(Low_Char+Num_Chars-1));

--	Pad out the remaining cells with the pad character.

Pad_LOOP:
   for i in (Out_Str'first+Num_Chars)..Out_Str'last loop
     Out_Str(i) := Pad_Char;
   end loop Pad_LOOP;

end PAR_STR_copy;


--

----------
Joe Hildebrand                          Fuentez Systems Concepts
hildjj@fuentez.com                      11781 Lee-Jackson Hwy, Suite 700
Software Engineer                       Fairfax, VA 22033
                                        Phone: (703)273-1447   
                                        Fax:   (703)273-2972

Standard disclaimers apply

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to assign STRINGs?
@ 1993-08-26 16:54 cis.ohio-state.edu!magnus.acs.ohio-state.edu!usenet.ins.cwru.edu!howland.
  0 siblings, 0 replies; 8+ messages in thread
From: cis.ohio-state.edu!magnus.acs.ohio-state.edu!usenet.ins.cwru.edu!howland. @ 1993-08-26 16:54 UTC (permalink / raw)


In article <1993Aug25.121754.20413@hellgate.utah.edu> matwood%peruvian.cs.utah.
edu@cs.utah.edu (Mark Atwood) writes:
>
>I'm kind of embarrassed asking this, after using Ada for over a year, but
>I was never very clear on unconstrained arrays, and now it's bitten me.
>
>Here is some representative code.
>
>
>  function GET_PARM return STRING;
>  -- from the vendor supplied DOS package
>
>  with TEXT_IO;
>  procedure ECHO is
>    subtype STR is STRING(1 .. 255);
>    CMDLINE : STR;
>  begin
>    CMDLINE := DOS.GET_PARMS;   -- get a CONTRAINT_ERROR here
>    TEXT_IO.PUT_LINE (CMDLINE);
>  end ECHO;
>
>
>So, how DO i assign the results of a function returning an unconstrained
>string to a constrained string?
>
>-- 
>Mark Atwood                  | My school and employer have too many problems
>matwood@peruvian.cs.utah.edu | without being blamed for mine.

have you tried
    CMDLINE (1..255) := Dos.Get_Parms;  
???

if so then you can use the text_io routines that use a string as input and pars
es it out.  

Unfortunately, all the "normal" tricks with array slices doesn't work when
a function has side effects (2 calls in a row give different results).

normally you can just do:
  cmdline(1..(dos.get_parms)'length) := dos.get_parms;
**** but ONLY if dos.get_parms doesn't change between the two calls.

Hopefully there is just an over-sight in the documentation on 
dos.get_parms.  Try the first example and see what happens.

Ken.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to assign STRINGs?
@ 1993-08-26 18:17 cis.ohio-state.edu!pacific.mps.ohio-state.edu!math.ohio-state.edu!howland
  0 siblings, 0 replies; 8+ messages in thread
From: cis.ohio-state.edu!pacific.mps.ohio-state.edu!math.ohio-state.edu!howland @ 1993-08-26 18:17 UTC (permalink / raw)


In article <CCDLMo.A8D@cs.uiuc.edu> rowe@cs.uiuc.edu (Kenneth E. Rowe) writes:

>   matwood%peruvian.cs.utah.edu@cs.utah.edu (Mark Atwood) writes:
>   >
>   >  function GET_PARM return STRING;
>   >  -- from the vendor supplied DOS package
>   >
>   >  with TEXT_IO;
>   >  procedure ECHO is
>   >    subtype STR is STRING(1 .. 255);
>   >    CMDLINE : STR;
>   >  begin
>   >    CMDLINE := DOS.GET_PARMS;   -- get a CONTRAINT_ERROR here
>   >    TEXT_IO.PUT_LINE (CMDLINE);
>   >  end ECHO;
>   >
>   >
>
>   have you tried
>       CMDLINE (1..255) := Dos.Get_Parms;  
>   ???

If you haven't tried it yet, don't bother.  Given the declaration of
CMDLINE, the following two statements are equivalent:

    CMDLINE := DOS.GET_PARMS;
    CMDLINE (1..255) := DOS.GET_PARMS;

so if one fails on a CONSTRAINT_ERROR, the other will fail also.
Other postings have already suggested alternatives that will work.

                                -- Adam

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to assign STRINGs?
@ 1993-08-27 15:35 cis.ohio-state.edu!math.ohio-state.edu!howland.reston.ans.net!noc.near.ne
  0 siblings, 0 replies; 8+ messages in thread
From: cis.ohio-state.edu!math.ohio-state.edu!howland.reston.ans.net!noc.near.ne @ 1993-08-27 15:35 UTC (permalink / raw)


In article <1993Aug25.121754.20413@hellgate.utah.edu> matwood%peruvian.cs.utah.
edu@cs.utah.edu (Mark Atwood) writes:

>So, how DO i assign the results of a function returning an unconstrained
>string to a constrained string?

Here's a solution I've found useful.  It relies on the fact that an 
unconstrained array can be constrained when the memory is allocated for
an access pointer (i.e., at run time).
It has the advantage of maintaining a string of the correct length, containing 
only the characters which are real (avoiding pad characters).
It has the disadvantage of using dynamic memory.

with Text_IO;
with Unchecked_Deallocation;
procedure ECHO is
  type String_Ptr_Type is access String;
  procedure Dispose is new Unchecked_Deallocation( String, String_Ptr_Type );
  CMDLINE_PTR: String_Ptr_Type;
begin
  CMDLINE_PTR := new String'(DOS.GET_PARMS);
  Text_IO.Put_Line( CMDLINE_PTR.all );
  ... other work with CMDLINE_PTR ... 
  Dispose( CMDLINE_PTR );
end ECHO;

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to assign STRINGs?
@ 1993-08-27 19:00 Tucker Taft
  0 siblings, 0 replies; 8+ messages in thread
From: Tucker Taft @ 1993-08-27 19:00 UTC (permalink / raw)


In article <1993Aug27.153504.1340@warm.inmet.com> 
  brennan@warm.inmet.com (William Brennan) writes:

>In article <1993Aug25.121754.20413@hellgate.utah.edu> 
  matwood%peruvian.cs.utah.edu@cs.utah.edu (Mark Atwood) writes:

>>So, how DO i assign the results of a function returning an unconstrained
>>string to a constrained string?
>
>Here's a solution I've found useful. . .
>It has the disadvantage of using dynamic memory.

[solution using allocator and unchecked deallocation omitted]

As has been pointed out by others, the following approach 
avoids the explicit allocator and deallocation:

with Text_IO;
with DOS;
procedure Echo is
  Cmd_Line : constant String := DOS.Get_Parms;
begin
  Text_IO.Put_Line(Cmd_Line);
  ... other work with Cmd_Line
end Echo;

The only reason to use an allocator might be to make the string
globally accessible.  However, presuming it is safe to call
the DOS package during library level elaboration, you could
just as easily have a global in some package:

with DOS;
pragma Elaborate(DOS);
package Parameters is
   Cmd_Line : constant String := DOS.Get_Parms;
  . . .
end Parameters;

Hope that helps...

S. Tucker Taft
Intermetrics, Inc.
Cambridge, MA  02138

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to assign STRINGs?
@ 1993-08-27 20:23 Robert I. Eachus
  0 siblings, 0 replies; 8+ messages in thread
From: Robert I. Eachus @ 1993-08-27 20:23 UTC (permalink / raw)


In article <HILDJJ.93Aug26100909@jupiter.fuentez.com> hildjj@jupiter.fuentez.co
m (Joe Hildebrand) writes:

  > NOTE: I don't claim this is pretty, but it seems to work.  It needs
  > some cleaning up, since this is one one the first functions we wrote
  > when we were learning Ada.  In particular, Out_Str should only be an
  > out parameter.  PAR_STR_Length returns the number of "useful"
  > characters in a string by subtracting the number of trailing spaces
  > and ascii.nul's.

  -- I don't like some of your (implied) requirements (I would make
  -- PAR_STR_copy a function and raise an exception instead of
  -- truncating), but try this as a "cleaned up" version:

   procedure PAR_STR_copy( Out_str   : out string;
			   In_Str    : in  string;
			   Pad_Char  : in  character := ' ' ) is 
     In_Str_Len: constant Integer := PAR_STR_length(In_Str);
   begin
     if In_Str_Len >= Out_Str'LENGTH
     then Out_Str := In_Str(In_Str'FIRST..In_Str'FIRST+Out_Str'LENGTH-1);
     else Out_Str := In_Str(In_Str'FIRST..In_Str'FIRST+In_Str_Len-1) &
                    String'(In_Str_Len-1..Out_Str'LENGTH => Pad_Char);
     end if;
   end PAR_STR_copy;
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to assign STRINGs?
@ 1993-09-03 18:18 dog.ee.lbl.gov!overload.lbl.gov!agate!doc.ic.ac.uk!uknet!mcsun!ub4b!cfmu!
  0 siblings, 0 replies; 8+ messages in thread
From: dog.ee.lbl.gov!overload.lbl.gov!agate!doc.ic.ac.uk!uknet!mcsun!ub4b!cfmu! @ 1993-09-03 18:18 UTC (permalink / raw)


In article <EACHUS.93Aug27152310@spectre.mitre.org> eachus@spectre.mitre.org (R
obert I. Eachus) writes:
>
>  -- try this as a "cleaned up" version:
>
>   procedure PAR_STR_copy( Out_str   : out string;
>			   In_Str    : in  string;
>			   Pad_Char  : in  character := ' ' ) is 
>     In_Str_Len: constant Integer := PAR_STR_length(In_Str);
>   begin
>     if In_Str_Len >= Out_Str'LENGTH
>     then Out_Str := In_Str(In_Str'FIRST..In_Str'FIRST+Out_Str'LENGTH-1);
>     else Out_Str := In_Str(In_Str'FIRST..In_Str'FIRST+In_Str_Len-1) &
>                    String'(In_Str_Len-1..Out_Str'LENGTH => Pad_Char);
>     end if;
>   end PAR_STR_copy;

Nice going Bob, but you were a bit over-focused on style I guess,
I would like to return Better_Ideas on this one :

                     String'(In_Str_Len+1..Out_Str'LENGTH => Pad_Char);
                                       ^^
or you get a CONSTRAINT_ERROR.

Hey, a new species of bug : off by 2 !   :-)

-- 
Stef VAN VLIERBERGHE            Eurocontrol - Central Flow Management Unit
stef@cfmu.eurocontrol.be        Avenue des Arts 19H
Tel: +32 2 729 33 42            B-1040 BRUSSELS
Fax: +32 2 729 32 16            Belgium

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: How to assign STRINGs?
@ 1993-09-07 21:56 Robert I. Eachus
  0 siblings, 0 replies; 8+ messages in thread
From: Robert I. Eachus @ 1993-09-07 21:56 UTC (permalink / raw)


In article <1993Sep3.181825.920@cfmu.eurocontrol.be> stef@cfmu.eurocontrol.be (
Stef Van Vlierberghe) writes:

   Newsgroups: comp.lang.ada
   Path: linus.mitre.org!linus!agate!doc.ic.ac.uk!uknet!mcsun!ub4b!cfmu!news
   From: stef@cfmu.eurocontrol.be (Stef Van Vlierberghe)
   Sender: news@cfmu.eurocontrol.be (News account)
   Date: Fri, 3 Sep 93 18:18:25 GMT
   References: <25gmc2$3cf@neomimsy.cs.umd.edu> <HILDJJ.93Aug26100909@jupiter.f
uentez.com> <EACHUS.93Aug27152310@spectre.mitre.org>
   Nntp-Posting-Host: cfmu
   Organization: Eurocontrol - Central Flow Management Unit
   Lines: 30

   In article <EACHUS.93Aug27152310@spectre.mitre.org> eachus@spectre.mitre.org
 (Robert I. Eachus) writes:

  > Nice going Bob, but you were a bit over-focused on style I guess,
  > I would like to return Better_Ideas on this one :

  >			String'(In_Str_Len+1..Out_Str'LENGTH => Pad_Char);
					  ^^
  > or you get a CONSTRAINT_ERROR.

    Mea culpa.

  > Hey, a new species of bug : off by 2 !   :-)

    Nope!  Old bug species.  Incorrect signs from double negation.  I
originally wrote In_Str_Len..Out_Str'LENGTH-1. (The catenation wipes
the actual indexes, all that matters is the length.)  But I moved the
correction to the first index as less confusing, and the usually
helpful SunAda compiler failed to do the symbolic arithmetic to
eliminate the run-time check.  (Not a compliant, since it catches most
of these cases.)  Next time I post something like this I'll have to
test it, not just compile it.

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~1993-09-07 21:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1993-08-27 19:00 How to assign STRINGs? Tucker Taft
  -- strict thread matches above, loose matches on Subject: below --
1993-09-07 21:56 Robert I. Eachus
1993-09-03 18:18 dog.ee.lbl.gov!overload.lbl.gov!agate!doc.ic.ac.uk!uknet!mcsun!ub4b!cfmu!
1993-08-27 20:23 Robert I. Eachus
1993-08-27 15:35 cis.ohio-state.edu!math.ohio-state.edu!howland.reston.ans.net!noc.near.ne
1993-08-26 18:17 cis.ohio-state.edu!pacific.mps.ohio-state.edu!math.ohio-state.edu!howland
1993-08-26 16:54 cis.ohio-state.edu!magnus.acs.ohio-state.edu!usenet.ins.cwru.edu!howland.
1993-08-26 14:09 Joe Hildebrand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox