Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Howard Page-Clark

On 06/8/12 3:26, Rainer Stratmann wrote:

procedure p1;
begin
  ...
end;



How to get all caller adresses of p1 in a program before p1 is executed?

For example p1 is called from 20 different places in a program.
Then I need the 20 caller adresses.


if by address you mean line number, then use the Find In Files dialog. 
Close all files in the Source Editor except the one containing p1 
procedures.

In the "Text to Find" field type p1.
In the "Where" radiogroup select "Search all open files".
Should give you a list of every occurrence of p1.

Howard

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Martin

On 06/08/2012 15:26, Rainer Stratmann wrote:

procedure p1;
begin
  ...
end;



How to get all caller adresses of p1 in a program before p1 is executed?

For example p1 is called from 20 different places in a program.
Then I need the 20 caller adresses.



At run time, or design time?

at design time, there is find in files, codetools "find references", or 
add "deprecated" and let compile and see the warnings.


At runtime, you can get the address, and if you have debug info, also 
the unit and line.

Run in debugger and use the stack window.
Or use (in your source code , needs console , or logfile) dumpstack();
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Rainer Stratmann
Am Monday 06 August 2012 18:43:04 schrieb Martin:
> > How to get all caller adresses of p1 in a program before p1 is executed?
> >
> > For example p1 is called from 20 different places in a program.
> > Then I need the 20 caller adresses.
>
> At run time, or design time?

At runtime.
I ment the (memory) caller adresses.

If p1 is executed I can get the caller adress with the rtl function:

get_caller_addr( get_frame );

But I want to scan the whole program before all p1's are called by the program 
to get all caller adresses of p1.

May be I write an own scan program to find all calling places which calls p1.

For that I need the memory adress where the program starts. And the length.

> At runtime, you can get the address, and if you have debug info, also
> the unit and line.
> Run in debugger and use the stack window.
> Or use (in your source code , needs console , or logfile) dumpstack();

I would like to do it without debug info.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Sven Barth

On 06.08.2012 19:28, Rainer Stratmann wrote:

Am Monday 06 August 2012 18:43:04 schrieb Martin:

How to get all caller adresses of p1 in a program before p1 is executed?

For example p1 is called from 20 different places in a program.
Then I need the 20 caller adresses.


At run time, or design time?


At runtime.
I ment the (memory) caller adresses.

If p1 is executed I can get the caller adress with the rtl function:

get_caller_addr( get_frame );

But I want to scan the whole program before all p1's are called by the program
to get all caller adresses of p1.

May be I write an own scan program to find all calling places which calls p1.

For that I need the memory adress where the program starts. And the length.



You know that scanning the binary code for calls is platform dependant? 
So you'd need to write that code for every CPU you want to support. Also 
this is much harder to do for CISC CPUs like x86 than for RISC CPUs 
(ARM, MIPS, etc), because the former have variable length opcodes. So 
you'd basically need to write a full blown dissembler...


Maybe it would be more interesting to know why you need this beforehand?

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Rainer Stratmann
Am Monday 06 August 2012 19:34:23 schrieb Sven Barth:
>
> You know that scanning the binary code for calls is platform dependant?
Yes.
[calling opcode] [calleradress]
calling opcode can differ and the byteorder of the adress can differ.

> So you'd need to write that code for every CPU you want to support. Also
> this is much harder to do for CISC CPUs like x86 than for RISC CPUs
> (ARM, MIPS, etc), because the former have variable length opcodes. So
> you'd basically need to write a full blown dissembler...
It seems hard. By now I support only 80x86 CPU's.

> Maybe it would be more interesting to know why you need this beforehand?
>
So you mean you can convince me to find another solution?

I need this for internationalisation.

p1( 'german snippet' );
is put in a table (caller adress and text) if calling the first time and 
translated in other languages.

If I have a list of all p1's I know which language snippet was already called 
and which snippet was not yet translated (called).

If there is a new snippet in the program and called at least one time it is 
added to the "must be translated list".


Another method would be if it would be possible to inc a constant at compile 
time!

const counter = 0;

p1( [counter++](at compiletime!) , 'german snippet');

But this is an insurmountable obstacle for the compilerprogrammers I think.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Sven Barth

On 06.08.2012 19:56, Rainer Stratmann wrote:

Am Monday 06 August 2012 19:34:23 schrieb Sven Barth:


You know that scanning the binary code for calls is platform dependant?

Yes.
[calling opcode] [calleradress]
calling opcode can differ and the byteorder of the adress can differ.



The problem here is the following:

Let's suppose the opcode for calling a function on x86 CPUs is 0xCA11. 
Now you scan through the code looking for 0xCA11 followed by 4 bit. The 
problem now is that without knowing the context of a found location 
0xCA11 you don't know whether it is really a call opcode or some 
immediate data that was passed to some previous opcode. This is also an 
obstacle experienced by VM developers for x86 instructions (or CISC 
instructions in general). For RISC instruction sets this is less 
complex, but the problem exists there as well.



So you'd need to write that code for every CPU you want to support. Also
this is much harder to do for CISC CPUs like x86 than for RISC CPUs
(ARM, MIPS, etc), because the former have variable length opcodes. So
you'd basically need to write a full blown dissembler...

It seems hard. By now I support only 80x86 CPU's.


Maybe it would be more interesting to know why you need this beforehand?


So you mean you can convince me to find another solution?

I need this for internationalisation.

p1( 'german snippet' );
is put in a table (caller adress and text) if calling the first time and
translated in other languages.

If I have a list of all p1's I know which language snippet was already called
and which snippet was not yet translated (called).

If there is a new snippet in the program and called at least one time it is
added to the "must be translated list".


Another method would be if it would be possible to inc a constant at compile
time!

const counter = 0;

p1( [counter++](at compiletime!) , 'german snippet');

But this is an insurmountable obstacle for the compilerprogrammers I think.


Out of curiosity: why don't you use resourcestrings?

And why do you need the count of calls (or usages)?

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Martin

On 06/08/2012 18:28, Rainer Stratmann wrote:

Am Monday 06 August 2012 18:43:04 schrieb Martin:

How to get all caller adresses of p1 in a program before p1 is executed?

For example p1 is called from 20 different places in a program.
Then I need the 20 caller adresses.

At run time, or design time?

At runtime.
I ment the (memory) caller adresses.



You can probably reuse sone code from the system unit.

below is a copy of dump_stack from fpc. It gets all the addresses


{$ifdef FPC_HAS_FEATURE_CONSOLEIO}
Procedure dump_stack(var f : text;bp : Pointer);
var
  i : Longint;
  prevbp : Pointer;
  is_dev : boolean;
  caller_frame,
  caller_addr : Pointer;
Begin
{$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
  try
{$endif FPC_HAS_FEATURE_EXCEPTIONS}
prevbp:=bp-1;
i:=0;
is_dev:=do_isdevice(textrec(f).Handle);
while bp > prevbp Do
 Begin
   caller_addr := get_caller_addr(bp);
   caller_frame := get_caller_frame(bp);
   if (caller_addr=nil) then
 break;
   Writeln(f,BackTraceStrFunc(caller_addr));
   if (caller_frame=nil) then
 break;
   Inc(i);
   If ((i>max_frame_dump) and is_dev) or (i>256) Then
 break;
   prevbp:=bp;
   bp:=caller_frame;
 End;
{$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
   except
 { prevent endless dump if an exception occured }
   end;
{$endif FPC_HAS_FEATURE_EXCEPTIONS}
End;

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Rainer Stratmann
Am Monday 06 August 2012 20:12:41 schrieb Sven Barth:
> The problem here is the following:
>
> Let's suppose the opcode for calling a function on x86 CPUs is 0xCA11.
> Now you scan through the code looking for 0xCA11 followed by 4 bit. 
Byte :-)
> The 
> problem now is that without knowing the context of a found location
> 0xCA11 you don't know whether it is really a call opcode or some
> immediate data that was passed to some previous opcode. This is also an
> obstacle experienced by VM developers for x86 instructions (or CISC
> instructions in general). For RISC instruction sets this is less
> complex, but the problem exists there as well.
If I have the opcode 0xCA11 and the adress of p1 (suppose) 0x6EF7CAB0 then I 
have 6 bytes (0xCA116EF7CAB0). That reduces drastically the possibility of 
some immediate random data. I have to search byte by byte then for the 6 
sequential bytes (48 Bits). :-)
>

...

> Out of curiosity: why don't you use resourcestrings?

It seems that is has not the flexibility and simplicity (in its entirety) that 
I want. Also it depends on a unit as I see. With resourestring a have to give 
every snippet a name. With my solution it is not necessary.  The names are 
automatically registered in a table (if called once).

> And why do you need the count of calls (or usages)?

I need the count of p1's to see if every snipped was already called by the 
program. This is important when adding a new language or if the original text 
snippets change.

Thers is a table with all snippets and a flag (*) if a snippet was already 
called by the program.

Text1*
Text2*
Text3*
Text4
Text5*
Text6
Text7*
Text8
Text9*
Text10*

4,6 and 8 was not called yet by the program.

But this I can only implement if it is possible to get the whole amount 
(memoryadresses and/or counts) of p1 in the whole program.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Rainer Stratmann
Am Monday 06 August 2012 20:15:53 schrieb Martin:
>
> You can probably reuse sone code from the system unit.
>
> below is a copy of dump_stack from fpc. It gets all the addresses
>
>
> {$ifdef FPC_HAS_FEATURE_CONSOLEIO}
> Procedure dump_stack(var f : text;bp : Pointer);
> var
>i : Longint;
>prevbp : Pointer;
>is_dev : boolean;
>caller_frame,
>caller_addr : Pointer;
> Begin
> {$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
>try
> {$endif FPC_HAS_FEATURE_EXCEPTIONS}
>  prevbp:=bp-1;
>  i:=0;
>  is_dev:=do_isdevice(textrec(f).Handle);
>  while bp > prevbp Do
>   Begin
> caller_addr := get_caller_addr(bp);
> caller_frame := get_caller_frame(bp);
> if (caller_addr=nil) then
>   break;
> Writeln(f,BackTraceStrFunc(caller_addr));
> if (caller_frame=nil) then
>   break;
> Inc(i);
> If ((i>max_frame_dump) and is_dev) or (i>256) Then
>   break;
> prevbp:=bp;
> bp:=caller_frame;
>   End;
> {$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
> except
>   { prevent endless dump if an exception occured }
> end;
> {$endif FPC_HAS_FEATURE_EXCEPTIONS}
> End;

I do not understand this ...
What is the content of the stack?
Which file 'f'?
Is it read from or write to file 'f'?
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Rainer Stratmann
Am Monday 06 August 2012 21:18:20 schrieb Rainer Stratmann:
> Am Monday 06 August 2012 20:15:53 schrieb Martin:
>
> I do not understand this ...
> What is the content of the stack?
> Which file 'f'?
> Is it read from or write to file 'f'?

Ok write to file 'f'. :-)
But I still do not understand.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Jonas Maebe

On 06 Aug 2012, at 21:06, Rainer Stratmann wrote:

> Am Monday 06 August 2012 20:12:41 schrieb Sven Barth:
>> The 
>> problem now is that without knowing the context of a found location
>> 0xCA11 you don't know whether it is really a call opcode or some
>> immediate data that was passed to some previous opcode. This is also an
>> obstacle experienced by VM developers for x86 instructions (or CISC
>> instructions in general). For RISC instruction sets this is less
>> complex, but the problem exists there as well.
> If I have the opcode 0xCA11 and the adress of p1 (suppose) 0x6EF7CAB0 then I 
> have 6 bytes (0xCA116EF7CAB0). That reduces drastically the possibility of 
> some immediate random data

It doesn't work like that. Regular calls use relative offsets on most (if not 
all) architectures we support. And in some cases we generate 
position-independent code, so then you'll have look at GOT entries to figure 
out the address. Then there are of course calls via procedure variables. And 
there's probably a ton more special cases I'm not thinking of right now.

>> Out of curiosity: why don't you use resourcestrings?
> 
> It seems that is has not the flexibility and simplicity (in its entirety) 
> that 
> I want.

I would not call your method "simple" and would also strongly recommend to use 
resourcestrings instead. Their purpose is exactly to make it easy to translate 
the strings in a program.


Jonas___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Rainer Stratmann
Am Monday 06 August 2012 21:26:24 schrieb Jonas Maebe:
> It doesn't work like that. Regular calls use relative offsets on most (if
> not all) architectures we support. And in some cases we generate
> position-independent code, so then you'll have look at GOT entries to
> figure out the address. Then there are of course calls via procedure
> variables. And there's probably a ton more special cases I'm not thinking
> of right now.

Would it then be possible to implement a counter (const) which is increased at 
compile time?
p1( increasedcounteratcompiletime , 'Textsnippet' ) ?

I guess it is not possible.

> >> Out of curiosity: why don't you use resourcestrings?
> >
> > It seems that is has not the flexibility and simplicity (in its entirety)
> > that I want.
>
> I would not call your method "simple"
It may is in the beginning more difficult to implement, but if it runs once I 
would say this can not get much more simpler.

You only have to put p1( ) around your text snippet. That is it!
The function returns the right language.

> and would also strongly recommend to 
> use resourcestrings instead. Their purpose is exactly to make it easy to
> translate the strings in a program.
That means more work to give every text snippet explicitly a name which is not 
necessary with my solution. And that means also less flexibility.

The resourcestring solution does not record the date and time when a text was 
changed and so on...
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Sven Barth

On 06.08.2012 21:48, Rainer Stratmann wrote:

Out of curiosity: why don't you use resourcestrings?


It seems that is has not the flexibility and simplicity (in its entirety)
that I want.


I would not call your method "simple"

It may is in the beginning more difficult to implement, but if it runs once I
would say this can not get much more simpler.

You only have to put p1( ) around your text snippet. That is it!
The function returns the right language.


Somehow this sounds like the GNU GetText function _() works. With the 
exception that the text which has to be translated is simply searched by 
looking through the source code for _("some text")...


Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Martin

On 06/08/2012 20:18, Rainer Stratmann wrote:

I do not understand this ...
What is the content of the stack?
Which file 'f'?
Is it read from or write to file 'f'?



f is just the STDOUT or logfile where the list of addresses is written 
to. You would likely use an array instead...


But let me say: I am with everyone else. Using stack/caller info is the 
wrong(est) way.


And if you need to ask "What is the content of the stack?" Then you 
should not use it.
All this functions are very low level. Usinc this kind of data implies 
having a very good understanding of the way the stack is organized.


---

Why do you not keep al ist of all the snippets you have seen (keep a 
copy of the text (strings are copy on write, so you do not need a real 
copy, just a 2nd string of the same text).

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Marco van de Voort
In our previous episode, Sven Barth said:
> > The function returns the right language.
> 
> Somehow this sounds like the GNU GetText function _() works. With the 
> exception that the text which has to be translated is simply searched by 
> looking through the source code for _("some text")...

Note that one of the problems of this is that it makes your text also the
key that identifies an unique piece of text. 

While I use (dx)gettext myself, I still think that is one of the
disadvantages.

P.s. the _() is not necessary with D2009+ anymore
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Aleksa Todorovic
On Mon, Aug 6, 2012 at 9:48 PM, Rainer Stratmann
 wrote:
> Am Monday 06 August 2012 21:26:24 schrieb Jonas Maebe:
>> It doesn't work like that. Regular calls use relative offsets on most (if
>> not all) architectures we support. And in some cases we generate
>> position-independent code, so then you'll have look at GOT entries to
>> figure out the address. Then there are of course calls via procedure
>> variables. And there's probably a ton more special cases I'm not thinking
>> of right now.
>
> Would it then be possible to implement a counter (const) which is increased at
> compile time?
> p1( increasedcounteratcompiletime , 'Textsnippet' ) ?
>
> I guess it is not possible.
>
>> >> Out of curiosity: why don't you use resourcestrings?
>> >
>> > It seems that is has not the flexibility and simplicity (in its entirety)
>> > that I want.
>>
>> I would not call your method "simple"
> It may is in the beginning more difficult to implement, but if it runs once I
> would say this can not get much more simpler.
>
> You only have to put p1( ) around your text snippet. That is it!
> The function returns the right language.
>
>> and would also strongly recommend to
>> use resourcestrings instead. Their purpose is exactly to make it easy to
>> translate the strings in a program.
> That means more work to give every text snippet explicitly a name which is not
> necessary with my solution. And that means also less flexibility.
>
> The resourcestring solution does not record the date and time when a text was
> changed and so on...

How about using memory for string constant to store pointer to
localized version - something like example below? Note: target
platform needs to support writable string constants, and there should
be enought ~ characters at the beginning of the string to store value
of pointer (4x~ for 32-bit pointers, 8x~ for 64bit pointers). If you
can meet these two conditions, you don't need to know internals of
compiler or any implementation detail.

program test_str_36;

uses
  sysutils;

function s(str: pchar): pchar;
var
  str2: pchar;
begin
  if str[0] = '~' then
  begin
// string is not localized
str2 := strnew('numero'); // localized version
ppchar(str)^ := str2;
  end;
  result := ppchar(str)^;
end;

var
  i: integer;
begin
  for i := 1 to 10 do
  begin
writeln(s('number'), ' ', i);
  end;
end.


> ___
> fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Rainer Stratmann
Am Monday 06 August 2012 22:17:11 schrieb Martin:
> But let me say: I am with everyone else. Using stack/caller info is the
> wrong(est) way.
I fully agree.
> And if you need to ask "What is the content of the stack?" Then you
> should not use it.
> All this functions are very low level. Usinc this kind of data implies
> having a very good understanding of the way the stack is organized.


> Why do you not keep al ist of all the snippets you have seen (keep a
> copy of the text (strings are copy on write, so you do not need a real
> copy, just a 2nd string of the same text).

Can you explain it more?
I want not search through the sourcecode, because it makes it less easy.


All I need is all caller adresses of p1 in the program.
Or an incremented counter at compiletime.
Both seems impossible by now.

If p1 is called then I can see which snippet was not yet called.
If the compilerincremented counter at the end is 500, then I need 500 snippet 
entries and I can see which entry already was called by the program during 
execution.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Martin

On 06/08/2012 21:39, Rainer Stratmann wrote

Can you explain it more?
I want not search through the sourcecode, because it makes it less easy.

How does an address like $040012a help you find the source?


All I need is all caller adresses of p1 in the program.
Or an incremented counter at compiletime.
Both seems impossible by now.

If p1 is called then I can see which snippet was not yet called.
If the compilerincremented counter at the end is 500, then I need 500 snippet
entries and I can see which entry already was called by the program during
execution.



I am still trying to understand what exactly you try to archive.

What I understand sofar:

-  your program has a fixed amount of text snippets in a given language
  QUESTION: are those snippets unique? Or can there be 2 individual 
snippets, that have the same text, but must be treated as different?

-  you want to implement a method that translates them
- you want to ensure this method was called exactly (or is it at least?) 
once, for each snippet.


For some reason that I do not understand yet, you need a unique 
identifier for each snippet.


Well if the text of the snippets is unique, then you can use the text 
itself.

So instead of using $040012a as token, you can use 'hello world'

--
That is, I still do not see, why you go this way at all.
You must have a list of all translations somewhere, and somehow you 
translate each snippet. For updating translations, you can

1) add each snippet that has no translation to a list
2) mark each translation, once it was used, and when the app finishes 
list all translations that where not used.


---
Or explain again what you try to do?


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Rainer Stratmann
Am Monday 06 August 2012 22:37:08 schrieb Aleksa Todorovic:
> program test_str_36;
>
> uses
>   sysutils;
>
> function s(str: pchar): pchar;
> var
>   str2: pchar;
> begin
>   if str[0] = '~' then
>   begin
> // string is not localized
> str2 := strnew('numero'); // localized version
> ppchar(str)^ := str2;
>   end;
>   result := ppchar(str)^;
> end;
>
> var
>   i: integer;
const prestr = '';
> begin
>   for i := 1 to 10 do
>   begin
> writeln( s( prestr + 'number' ),  ' ' ,   i);
>   end;
> end.

That seems somehow interesting.
But you have to put it everywhere in front.
May be a macro can do it so that you have only s() left.
And may be (but not very likely when reading the statement of Jonas) you can 
search the whole program for '' to get the caller adresses of s().
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Martin

On 06/08/2012 21:57, Martin wrote:


I am still trying to understand what exactly you try to archive.


Ok, I read one of the other posts: Do you need to ensure to handle each 
snippet only once?



Are *ALL* snippets constants?
either
  const t1 = 'abc';
or
  foo('text')

and NEVER result of
- a function snip := copy('aaa',1,2) or snip := foo();
- any operation, such as concatenation: snip := s1+s2;


If the are: use the address of the first char in the snippet
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Rainer Stratmann
Am Monday 06 August 2012 22:57:42 schrieb Martin:
> On 06/08/2012 21:39, Rainer Stratmann wrote
>
> > Can you explain it more?
> > I want not search through the sourcecode, because it makes it less easy.
>
> How does an address like $040012a help you find the source?

If I have a list with all caller adresses then I know which one was already 
called and I can faster search this if only handle the adress (speed reason).

> > All I need is all caller adresses of p1 in the program.
> > Or an incremented counter at compiletime.
> > Both seems impossible by now.
> >
> > If p1 is called then I can see which snippet was not yet called.
> > If the compilerincremented counter at the end is 500, then I need 500
> > snippet entries and I can see which entry already was called by the
> > program during execution.
>
> I am still trying to understand what exactly you try to archive.

I am sure you mean achieve :-)

> What I understand sofar:
>
> -  your program has a fixed amount of text snippets in a given language
yes
>QUESTION: are those snippets unique? Or can there be 2 individual
> snippets, that have the same text, but must be treated as different?
both, I will able to handle it p1, p_unique, and so on.
> -  you want to implement a method that translates them
yes
> - you want to ensure this method was called exactly (or is it at least?)
> once, for each snippet.
No.
I want to register a call.
I (fast) search through the adress-table every time. If the adress is in the 
table then I have already the translated pchar at array nr x. If not I have 
to translate the string and add the caller adress to the table and the pchar 
to the translated string.
Further on I can do with the table and string snippets what I want. If I have 
an Idea in the future I can implement. For example adding date and time of 
changes and so on.
>
> For some reason that I do not understand yet, you need a unique
> identifier for each snippet.
> Well if the text of the snippets is unique, then you can use the text
> itself.
> So instead of using $040012a as token, you can use 'hello world'
see above.
>
> --
> That is, I still do not see, why you go this way at all.
> You must have a list of all translations somewhere, and somehow you
> translate each snippet.
I want the text to stay in the sourcecode and not want to have some kind of 
excel-list.
> For updating translations, you can 
> 1) add each snippet that has no translation to a list
> 2) mark each translation, once it was used, and when the app finishes
> list all translations that where not used.
For that I have to call every s() in the program, because I do not have a 
fixed list.
To know if every s() in the program was called it would be good to know every 
presence of s().
I tried also a kind of excel list with unique identifyer for each snippet, but 
for me it seems not flexible enough and much work instead of putting s() 
around every snippet.
>
> ---
> Or explain again what you try to do?
The translation should be done by a web based interface from the inhabitant of 
every country (simplicity, less work for me). So I need a registration and I 
need to be flexible. Snippets can change, and so on. It would be good to save  
the older snippets if one has changed... All this can be implemented. Date & 
Timestamp...
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Rainer Stratmann
Am Monday 06 August 2012 23:36:10 schrieb Martin:
> On 06/08/2012 21:57, Martin wrote:
> > I am still trying to understand what exactly you try to archive.
>
> Ok, I read one of the other posts: Do you need to ensure to handle each
> snippet only once?
>
>
> Are *ALL* snippets constants?
yes, but they are most time immediately in s( 'snippet' );
> either
>const t1 = 'abc';
> or
>foo('text')
Foo I don't know by now. So guess I will not use it.

> and NEVER result of
> - a function snip := copy('aaa',1,2) or snip := foo();
> - any operation, such as concatenation: snip := s1+s2;
right.
>
> If the are: use the address of the first char in the snippet
?
But then I do not have a list of all caller adresses of s() which I try to 
get.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Sven Barth

On 06.08.2012 22:22, Marco van de Voort wrote:

In our previous episode, Sven Barth said:

The function returns the right language.


Somehow this sounds like the GNU GetText function _() works. With the
exception that the text which has to be translated is simply searched by
looking through the source code for _("some text")...


Note that one of the problems of this is that it makes your text also the
key that identifies an unique piece of text.

While I use (dx)gettext myself, I still think that is one of the
disadvantages.

P.s. the _() is not necessary with D2009+ anymore


Which reminds me: Delphi uses a different style of resource string 
system. In FPC you can set up the resourcestrings table based while in 
Delphi a "LoadResString" function is used each time a resourcestring is 
accessed. You can override the default functionality by setting a 
corresponding procedure variable. See also here 
http://docwiki.embarcadero.com/Libraries/en/System.LoadResString


It wouldn't solve the problem of "declaring a resourcestring" though and 
also the function doesn't get the "resource string identifier" as the 
table based function in FPC currently gets... so in that regard the 
system seems more limited (while it has some positive aspects as well).


Regards,
Sven

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Martin

On 06/08/2012 22:46, Rainer Stratmann wrote:

If the are: use the address of the first char in the snippet

?
But then I do not have a list of all caller adresses of s() which I try to
get.



I still do not understand what is so special about the caller address? 
Furthermore, you said yourself, you do not need it. You can also live 
withe a "number that the compiler generates at compilation time".


so if you had
p(next_compile_time_number, 'text');

then all p gets is 109, 'text'
if that 109 does help, why not the address of the 1st char?


---
I know there is still something about your idea that I havent got 
which makes this a bit hard.


Lets take a step back:

Why do you not just store all snippets in a stringlist, if p saw them? 
(speed should not be a reason, that can be dealt with)


You can always extend the list to store additional info per field.

---
ps
foo = placeholder
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-06 Thread Mark Morgan Lloyd

Rainer Stratmann wrote:


All I need is all caller adresses of p1 in the program.


You might be able to do that sort of thing by running the program with a 
profiler and analyzing all captured stacks. But it would be a vast 
amount of effort, and unless you could guarantee 100% coverage (i.e. 
feeding the program all possible input states etc.) you'd probably miss 
combinations.


You're left with the options of learning how to use resourcestrings 
effectively, or using a language such as Smalltalk where the senders of 
a message are known in advance.


--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-07 Thread Rainer Stratmann
Am Tuesday 07 August 2012 00:02:02 schrieb Martin:
> I still do not understand what is so special about the caller address?
> Furthermore, you said yourself, you do not need it. You can also live
> withe a "number that the compiler generates at compilation time".

With all caller adresses OR all numbers (see down) I have the whole amount of 
snippets that I want to have.

The caller adress is a unique identifier.
A handle.

> so if you had
> p(next_compile_time_number, 'text');

I do not write something about 'next_compile_time_number'.
My words were 'incremented counter at compiletime'.

That means the counter increases immediately after every occurence in the 
sourcecode.

> then all p gets is 109, 'text'
> if that 109 does help, why not the address of the 1st char?
>
>
> ---
> I know there is still something about your idea that I havent got
> which makes this a bit hard.

I want to have all caller adresses of s() before s() is called.

> Lets take a step back:
>
> Why do you not just store all snippets in a stringlist, if p saw them?
I do it.
But I need the information which snippet was not called yet.
That is all I want.
> (speed should not be a reason, that can be dealt with)
>
> You can always extend the list to store additional info per field.
Yes, I know :-)
>
> ---
> ps
> foo = placeholder
ok thanks.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-07 Thread Martin

On 07/08/2012 08:22, Rainer Stratmann wrote:

Am Tuesday 07 August 2012 00:02:02 schrieb Martin:

I still do not understand what is so special about the caller address?
Furthermore, you said yourself, you do not need it. You can also live
withe a "number that the compiler generates at compilation time".

With all caller adresses OR all numbers (see down) I have the whole amount of
snippets that I want to have.

How?

I can see 2 ways you get that address

procedure p (snip:string);
begin
  calleraddr := get_caller_addr(); //needs to be implemented
  ..
end

 OR
procedure p (snip:string, caller_addr:pointer);

and when calling
p('hello world', get_my_addr()); // needs to be implemented

*** BUT
then you run your app. You collect maybe (for example) 42 addresses with 
snippets


How do you know that is all of them? There may be places that call p() 
but that where not executed. Then you do not have that address, so you 
do not know it is missing



The caller adress is a unique identifier.
A handle.
**IF** each snippet is unique (that is if each text exists only once) 
Then the text itself can be used as a unique ID


yes it is longer, and compares slower, but a hash table can solve that


so if you had
p(next_compile_time_number, 'text');

I do not write something about 'next_compile_time_number'.
My words were 'incremented counter at compiletime'.
That means the counter increases immediately after every occurence in the
sourcecode.
That is what I meant: Take  'next_compile_time_number' as a macro or 
preprocesser driective


Now in that case, if you know the highest number (but you do not know 
it), you would be able to check completness



then all p gets is 109, 'text'
if that 109 does help, why not the address of the 1st char?


---
I know there is still something about your idea that I havent got
which makes this a bit hard.

I want to have all caller adresses of s() before s() is called.

what do you mean before s is called?

You want the compiler (at compile time) to build a table (array) of all 
places that call p, so you can check if they called?

That is something you never said (or I missed it)


Lets take a step back:

Why do you not just store all snippets in a stringlist, if p saw them?

I do it.
But I need the information which snippet was not called yet.
That is all I want.

See above. I have yet to know, how that works with the caller address

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-07 Thread Rainer Stratmann
Am Tuesday 07 August 2012 11:34:10 schrieb Martin:
> > With all caller adresses OR all numbers (see down) I have the whole
> > amount of snippets that I want to have.
>
> How?

With the compiler keyword 'calleradresstable';

function s( str : pchar ) : pchar; calleradresstable;

Then the compiler makes a table of all calleradresses and also the amount of 
s() in the program.
With the rtl function getcalleradresstable() then I get a pointer and the 
amount of the array.

> I can see 2 ways you get that address
>
> procedure p (snip:string);
> begin
>calleraddr := get_caller_addr(); //needs to be implemented
>..
> end

It exists already:
http://www.freepascal.org/docs-html/rtl/system/get_caller_addr.html

>   OR
> procedure p (snip:string, caller_addr:pointer);
> 
> and when calling
> p('hello world', get_my_addr()); // needs to be implemented
>
> *** BUT
> then you run your app. You collect maybe (for example) 42 addresses with
> snippets
>
> How do you know that is all of them? There may be places that call p()
> but that where not executed. Then you do not have that address, so you
> do not know it is missing

That is the point.

>
> > The caller adress is a unique identifier.
> > A handle.
>
> **IF** each snippet is unique (that is if each text exists only once)
> Then the text itself can be used as a unique ID

Then I also need all adresses from the snippets before all s() are called.
Method 'caller adress' is easier and clearly.

>
> yes it is longer, and compares slower, but a hash table can solve that

I prefer faster execution wherever it is possible with little effort.

> >> so if you had
> >> p(next_compile_time_number, 'text');
> >
> > I do not write something about 'next_compile_time_number'.
> > My words were 'incremented counter at compiletime'.
> > That means the counter increases immediately after every occurence in the
> > sourcecode.
>
> That is what I meant: Take  'next_compile_time_number' as a macro or
> preprocesser driective
???
> Now in that case, if you know the highest number (but you do not know
> it), you would be able to check completness
Yes, but the number doesn't exist. I think we talk again about 2 different 
things here.
>
> You want the compiler (at compile time) to build a table (array) of all
> places that call p, so you can check if they called?
> That is something you never said (or I missed it)

I say it the whole time. Beginning with the first post of this thread. Sven 
wanted to know why I need this, so we are discussing the snippet things now.

> >> Lets take a step back:
> >>
> >> Why do you not just store all snippets in a stringlist, if p saw them?
> >
> > I do it.
> > But I need the information which snippet was not called yet.
> > That is all I want.
>
> See above. I have yet to know, how that works with the caller address

http://www.freepascal.org/docs-html/rtl/system/get_caller_addr.html
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-07 Thread Martin

On 07/08/2012 17:58, Rainer Stratmann wrote:

With the compiler keyword 'calleradresstable';

function s( str : pchar ) : pchar; calleradresstable;

Then the compiler makes a table of all calleradresses and also the amount of
s() in the program.
With the rtl function getcalleradresstable() then I get a pointer and the
amount of the array.


Interesting. I couldn't find any documentation on them, and fpc 2.6.0 
does give an error.


But yes, with this added info, I can at least see what you try todo.


I can see 2 ways you get that address

procedure p (snip:string);
begin
calleraddr := get_caller_addr(); //needs to be implemented
..
end

It exists already:
http://www.freepascal.org/docs-html/rtl/system/get_caller_addr.html
I knew there was something like it. But didnt have the name. So I gave a 
dummy name, and commented it.


But now, I have another question:

Despite calleradresstable not working for me, if it does for you, then 
what is the problem?


Sure get_caller_addr() returns the "return address" so it will differ. I do not 
know haw big the offset can be at max. But unless you include a disassembler, or 
debug-line info, you can not get exact details.
But likely you can assume a maximum offset (depending if calleradresstable is 
the asm or pascal statement address).


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-07 Thread Rainer Stratmann
Am Tuesday 07 August 2012 19:13:29 schrieb Martin:
> On 07/08/2012 17:58, Rainer Stratmann wrote:
> > With the compiler keyword 'calleradresstable';
> >
> > function s( str : pchar ) : pchar; calleradresstable;
> >
> > Then the compiler makes a table of all calleradresses and also the amount
> > of s() in the program.
> > With the rtl function getcalleradresstable() then I get a pointer and the
> > amount of the array.
>
> Interesting. I couldn't find any documentation on them, and fpc 2.6.0
> does give an error.

That is my wish to a compiler programmer.
Can one hear me?
Who programs the compiler?

> But yes, with this added info, I can at least see what you try todo.
>
> >> I can see 2 ways you get that address
> >>
> >> procedure p (snip:string);
> >> begin
> >> calleraddr := get_caller_addr(); //needs to be implemented
> >> ..
> >> end
> >
> > It exists already:
> > http://www.freepascal.org/docs-html/rtl/system/get_caller_addr.html
>
> I knew there was something like it. But didnt have the name. So I gave a
> dummy name, and commented it.
>
> But now, I have another question:
>
> Despite calleradresstable not working for me, if it does for you, then
> what is the problem?
>
> Sure get_caller_addr() returns the "return address" so it will differ.
It returns a _unique_ handle. That is what I need.
Perhaps there will be some offset.
May be a compiler programmer can get the exact adresses and table for this 
wish.
> I do 
> not know haw big the offset can be at max. But unless you include a
> disassembler, or debug-line info, you can not get exact details. But likely
> you can assume a maximum offset (depending if calleradresstable is the asm
> or pascal statement address).
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Get all caller adresses of a procedure/function

2012-08-07 Thread Martin

On 07/08/2012 18:25, Rainer Stratmann wrote:

Am Tuesday 07 August 2012 19:13:29 schrieb Martin:

On 07/08/2012 17:58, Rainer Stratmann wrote:

function s( str : pchar ) : pchar; calleradresstable;

Then the compiler makes a table of all calleradresses and also the amount
of s() in the program.

Interesting. I couldn't find any documentation on them, and fpc 2.6.0
does give an error.

That is my wish to a compiler programmer.
Can one hear me?
Who programs the compiler?

http://www.freepascal.org/aboutus.var



Sure get_caller_addr() returns the "return address" so it will differ.

It returns a _unique_ handle. That is what I need.
Perhaps there will be some offset.


You seem to throw to issues together again. the unique handle issue is 
solvable without this. This is only needed to get a complete list of 
snippets...


I got the feeling, that this feature may not happen (but I have no 
knowledge). I do not eve know if it can be done, since the compiler does 
not even know the entire list of all callers. That is the linker. and 
the linker is platform dependent, and at least on some platforms not 
part of fpc  (At least as far as I know).


--
Anyway: lets get pack to your problem.

You need a list of all snippets (or a list of IDs that can be mapped 1 
to 1 to the snippets).


I haven't got the solution

But I can suggest 2 topics for investigations

1) Resourcestrings.

You do not need to use the po attempt. BUt I would EXPECT that it is 
possible (and you can write your own code for that) to get a list of all 
resource strings in the app. So there would be the table you need.


The IDE can help you to create resourestrings from the constants in the 
code (though it is a bit of work)


2) The new extended RTTI? I have no idea. I do not even know how ready 
it is. It may not apply at all BUt you could ask around


3) Write your own pre-processor


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal