comp.lang.ada
 help / color / mirror / Atom feed
* Using controlled types to trace program execution
@ 2002-02-26 13:39 Nige
  2002-02-26 18:26 ` tmoran
  2002-03-06 15:20 ` Matthew Heaney
  0 siblings, 2 replies; 9+ messages in thread
From: Nige @ 2002-02-26 13:39 UTC (permalink / raw)


Hi all,

I am trying to come up with a way of tracing program execution using
controlled types. Ie, I want to be able to declare an object as a
procedure or function is entered, which would add itself to some sort of
stack during it's initialization and remove itself once it goes out of
scope.

The benfit of this is that I would not have to explicitly have some sort
of enter and exit calls whenever a subprogram is called.

The problem is, that however I try to identify the declaration of the
object, the compiler throws it out.

The approaches I have tried are:

* A controlled object with an access to a string as a discriminant.

* A generic package containing a controlled type with a discrete type as
a discriminant.

* extending the type with a string/string access to identify it.

Does anyone have any ideas how I could acomplish this or even if it is
possible? I may be trying to do something that is not sensible/possible
of course...

Ideally I'd simply like to have:

procedure Something is

  Here : Trace.Location ("Something");

begin
  null;
end Something;

 ... where the package Trace would store the string "Something" until
the object Here goes out of scope. Then at any time I can examine the
contents of the stack in the package Trace...

The nearest I have got is to use new to allocate strings as the objects
are declared, but then the strings can't be deallocated explicitly,
because the strings are not variables.
eg

  Here : Trace.Location (new String'("Something"));

Hope I've made some sense,

Nige



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

* Re: Using controlled types to trace program execution
  2002-02-26 13:39 Nige
@ 2002-02-26 18:26 ` tmoran
  2002-02-27 11:44   ` Nige
  2002-03-06 15:20 ` Matthew Heaney
  1 sibling, 1 reply; 9+ messages in thread
From: tmoran @ 2002-02-26 18:26 UTC (permalink / raw)


> I am trying to come up with a way of tracing program execution using
> controlled types. Ie, I want to be able to declare an object as a
> ...
> * A controlled object with an access to a string as a discriminant.
>
> * A generic package containing a controlled type with a discrete type as
  A combination will do the job.
  You can't pass a string as a discriminant to your controlled type, and if
you pass an access-to-string type it will be a constant and you won't
be able to "free" the string.  But you can do it with two levels:
  type p is access string;
  type t(msg : access p) is new ada.finalization.limited_controlled with ...
Then use the generic instantiation as a shorthand for declaring an
aliased pointer to a new string'("something") followed by a declaration
of the controlled type with a 'access to that pointer as its parameter.
  Your compiler vendor may supply an easier way of tracing execution.
If you really need to do it this way, here's a working example:

with ada.finalization;
package trt is
  type p is access string;
  type t(msg : access p) is new ada.finalization.limited_controlled with null record;
  procedure initialize(x: in out t);
  procedure finalize(x: in out t);
end trt;

with ada.text_io;
with ada.unchecked_deallocation;
package body trt is
  procedure initialize(x: in out t) is
  begin
    ada.text_io.put_line("init " & x.msg.all.all);
  end initialize;
  procedure free is new ada.unchecked_deallocation(string,p);
  procedure finalize(x: in out t) is
  begin
    ada.text_io.put_line("fini " & x.msg.all.all);
    free(x.msg.all);
  end finalize;
end trt;

with trt;
generic
  msg : string;
package trace is
private
  x : aliased trt.p := new string'(msg);
  follower : trt.t(x'access);
end trace;

-- usage
with ada.text_io;
with trace;
procedure trtest is
  procedure p1 is
    package tracer is new trace("trace p1");
  begin
    ada.text_io.put_line("in p1");
  end p1;
  procedure p2 is
    package tracer is new trace("trace p2");
  begin
    ada.text_io.put_line("start p2");
    p1;
    ada.text_io.put_line("end p2");
  end p2;
begin
  p1;
  p2;
end trtest;



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

* Re: Using controlled types to trace program execution
  2002-02-26 18:26 ` tmoran
@ 2002-02-27 11:44   ` Nige
  0 siblings, 0 replies; 9+ messages in thread
From: Nige @ 2002-02-27 11:44 UTC (permalink / raw)


tmoran@acm.org wrote:
> 
   A combination will do the job.
>   You can't pass a string as a discriminant to your controlled type, and if
> you pass an access-to-string type it will be a constant and you won't
> be able to "free" the string.  But you can do it with two levels:
>   type p is access string;
>   type t(msg : access p) is new ada.finalization.limited_controlled with ...
> Then use the generic instantiation as a shorthand for declaring an
> aliased pointer to a new string'("something") followed by a declaration
> of the controlled type with a 'access to that pointer as its parameter.

Thanks - I hadn't thought about declaring a package - only a variable.

Nige



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

* Re: Using controlled types to trace program execution
@ 2002-02-27 11:55 Christoph Grein
  2002-02-27 17:59 ` Jeffrey Carter
  0 siblings, 1 reply; 9+ messages in thread
From: Christoph Grein @ 2002-02-27 11:55 UTC (permalink / raw)


Dynamic allocation and deallocation are not necessary:

generic

  Unit_Name: String;

package Trace is

private

  X: aliased String := Unit_Name;
  Follower: T (X'Access);

end Trace;

> tmoran@acm.org wrote:
> > 
>    A combination will do the job.
> >   You can't pass a string as a discriminant to your controlled type, and if
> > you pass an access-to-string type it will be a constant and you won't
> > be able to "free" the string.  But you can do it with two levels:
> >   type p is access string;
> >   type t(msg : access p) is new ada.finalization.limited_controlled with ...
> > Then use the generic instantiation as a shorthand for declaring an
> > aliased pointer to a new string'("something") followed by a declaration
> > of the controlled type with a 'access to that pointer as its parameter.
> 
> Thanks - I hadn't thought about declaring a package - only a variable.
> 
> Nige
> _______________________________________________
> comp.lang.ada mailing list
> comp.lang.ada@ada.eu.org
> http://ada.eu.org/mailman/listinfo/comp.lang.ada



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

* Re: Using controlled types to trace program execution
  2002-02-27 11:55 Using controlled types to trace program execution Christoph Grein
@ 2002-02-27 17:59 ` Jeffrey Carter
  2002-02-28 15:24   ` Nige
  0 siblings, 1 reply; 9+ messages in thread
From: Jeffrey Carter @ 2002-02-27 17:59 UTC (permalink / raw)


Christoph Grein wrote:
> 
> Dynamic allocation and deallocation are not necessary:
> 
> generic
> 
>   Unit_Name: String;
> 
> package Trace is
> 
> private
> 
>   X: aliased String := Unit_Name;
>   Follower: T (X'Access);
> 
> end Trace;

And you can use the Unit_Name constant from PragmARC.Reflection (from
the PragmAda Reusable Components) to avoid manually supplying the unit
name (and forgetting to change it when the nesting changes).

-- 
Jeffrey Carter



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

* Re: Using controlled types to trace program execution
  2002-02-27 17:59 ` Jeffrey Carter
@ 2002-02-28 15:24   ` Nige
  0 siblings, 0 replies; 9+ messages in thread
From: Nige @ 2002-02-28 15:24 UTC (permalink / raw)


Jeffrey Carter wrote:
> 
> Christoph Grein wrote:
> >
> > Dynamic allocation and deallocation are not necessary:
> >
> > generic
> >
> >   Unit_Name: String;
> >
> > package Trace is
> >
> > private
> >
> >   X: aliased String := Unit_Name;
> >   Follower: T (X'Access);
> >
> > end Trace;
> 
> And you can use the Unit_Name constant from PragmARC.Reflection (from
> the PragmAda Reusable Components) to avoid manually supplying the unit
> name (and forgetting to change it when the nesting changes).

Thanks guys - I've come up with a hybrid which seems to do the job for
me.

Nige.



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

* Re: Using controlled types to trace program execution
  2002-02-26 13:39 Nige
  2002-02-26 18:26 ` tmoran
@ 2002-03-06 15:20 ` Matthew Heaney
  2002-03-07  8:56   ` Nige
  1 sibling, 1 reply; 9+ messages in thread
From: Matthew Heaney @ 2002-03-06 15:20 UTC (permalink / raw)



"Nige" <nigel.scott@uk.thalesgroup.com> wrote in message
news:3C7B9007.FB5F257D@uk.thalesgroup.com...
> procedure Something is
>
>   Here : Trace.Location ("Something");
>
> begin
>   null;
> end Something;

Try this:

with Ada.Finalization;
package Trace is

   type Location (S : access String) is limited private;

private

   type Location (S : access String) is
      new Ada.Finalization.Limited_Controlled with null record;

   procedure Initialize (L : in out Location);
   procedure Finalize (L : in out Location);

end Trace;


with Trace;
procedure Op is
   S : aliased String := "Op";
   Here : Trace.Location (S'Access);
begin
   null;
end;


You have to declare the string object as aliased.  You don't need heap for
what you're trying to do.






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

* Re: Using controlled types to trace program execution
  2002-03-06 15:20 ` Matthew Heaney
@ 2002-03-07  8:56   ` Nige
  2002-03-07 16:43     ` Jeffrey Carter
  0 siblings, 1 reply; 9+ messages in thread
From: Nige @ 2002-03-07  8:56 UTC (permalink / raw)


Matthew Heaney wrote:
> 
> "Nige" <nigel.scott@uk.thalesgroup.com> wrote in message
> news:3C7B9007.FB5F257D@uk.thalesgroup.com...
> > procedure Something is
> >
> >   Here : Trace.Location ("Something");
> >
> > begin
> >   null;
> > end Something;
> 
> Try this:
> 
> with Ada.Finalization;
> package Trace is
> 
>    type Location (S : access String) is limited private;
> 
> private
> 
>    type Location (S : access String) is
>       new Ada.Finalization.Limited_Controlled with null record;
> 
>    procedure Initialize (L : in out Location);
>    procedure Finalize (L : in out Location);
> 
> end Trace;
> 
> with Trace;
> procedure Op is
>    S : aliased String := "Op";
>    Here : Trace.Location (S'Access);
> begin
>    null;
> end;
> 
> You have to declare the string object as aliased.  You don't need heap for
> what you're trying to do.

Thanks - that does solve my original problem, but what I was ultimately
after was a single declaration to keep it as simple as possible, the
idea being that as subprograms are created, a single line can be cut and
pasted into each one.

What I've got working now allows me to just do:

procedure Something is
  package Unit is new Trace;
begin
  null;
end Something;

Cheers,
Nige.



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

* Re: Using controlled types to trace program execution
  2002-03-07  8:56   ` Nige
@ 2002-03-07 16:43     ` Jeffrey Carter
  0 siblings, 0 replies; 9+ messages in thread
From: Jeffrey Carter @ 2002-03-07 16:43 UTC (permalink / raw)


Nige wrote:
> 
> What I've got working now allows me to just do:
> 
> procedure Something is
>   package Unit is new Trace;
> begin
>   null;
> end Something;

What does your complete solution look like now? Inquiring minds want to
know.

-- 
Jeffrey Carter



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

end of thread, other threads:[~2002-03-07 16:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-02-27 11:55 Using controlled types to trace program execution Christoph Grein
2002-02-27 17:59 ` Jeffrey Carter
2002-02-28 15:24   ` Nige
  -- strict thread matches above, loose matches on Subject: below --
2002-02-26 13:39 Nige
2002-02-26 18:26 ` tmoran
2002-02-27 11:44   ` Nige
2002-03-06 15:20 ` Matthew Heaney
2002-03-07  8:56   ` Nige
2002-03-07 16:43     ` Jeffrey Carter

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