Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2013-10

WriteLn back to the GUI

66 messages · 15 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

ListMember

Hello,

I am trying to find where WriteLn is declared; but, apparently, WriteLn is among the select few that Lazarus will ignore 'Find Declaration' requests --at least that's how it behaves (latest Lazarus stable) on my side.

My ultimate goal, after finding where it is declared, is to locally modify that part of the sources so that (instead of writing to the console) it will use a global callback to display whatever WriteLn'ed in a TMemo.

Or, is there already an alternative to redirect console output to the running GUI?

Lukasz Sokol
to ListMember
ListMember wrote 15 lines
Hello, I am trying to find where WriteLn is declared; but, apparently, WriteLn is among the select few that Lazarus will ignore 'Find Declaration' requests --at least that's how it behaves (latest Lazarus stable) on my side. My ultimate goal, after finding where it is declared, is to locally modify that part of the sources so that (instead of writing to the console) it will use a global callback to display whatever WriteLn'ed in a TMemo. Or, is there already an alternative to redirect console output to the running GUI?

DebugLn() ?

-L.

ListMember
to Lukasz Sokol
Lukasz Sokol wrote 17 lines
On 23/10/13 07:59, ListMember wrote: > Hello, > > I am trying to find where WriteLn is declared; but, apparently, > WriteLn is among the select few that Lazarus will ignore 'Find > Declaration' requests --at least that's how it behaves (latest > Lazarus stable) on my side. > > My ultimate goal, after finding where it is declared, is to locally > modify that part of the sources so that (instead of writing to the > console) it will use a global callback to display whatever WriteLn'ed > in a TMemo. > > Or, is there already an alternative to redirect console output to the > running GUI? > DebugLn() ?

I don't really want to alter the sources (which are more than 100 units).

I'd rather find the unit where WriteLn() procedure is defined and alter it once and recompile FPC/Lazarus.

But, I just can't locate where WriteLn procedure is defined. I did a grep (equivalent in Windows) but came up with nothing usable.

Michael Van Canneyt
to ListMember
ListMember wrote 26 lines
On 2013-10-23 11:33, Lukasz Sokol wrote: > On 23/10/13 07:59, ListMember wrote: >> Hello, >> >> I am trying to find where WriteLn is declared; but, apparently, >> WriteLn is among the select few that Lazarus will ignore 'Find >> Declaration' requests --at least that's how it behaves (latest >> Lazarus stable) on my side. >> >> My ultimate goal, after finding where it is declared, is to locally >> modify that part of the sources so that (instead of writing to the >> console) it will use a global callback to display whatever WriteLn'ed >> in a TMemo. >> >> Or, is there already an alternative to redirect console output to the >> running GUI? >> > DebugLn() ? I don't really want to alter the sources (which are more than 100 units). I'd rather find the unit where WriteLn() procedure is defined and alter it once and recompile FPC/Lazarus. But, I just can't locate where WriteLn procedure is defined. I did a grep (equivalent in Windows) but came up with nothing usable.

This routine does not exist. It is handled specially by the compiler.

What you must do is something similar to what the crt unit does, and assign() the input/output files to a special file handler.

Michael.

leledumbo
to ListMember: I am trying to find where WriteLn is declared; but, apparently, WriteLn is among the…
I am trying to find where WriteLn is declared; but, apparently, WriteLn

is among the select few that Lazarus will ignore 'Find Declaration' requests --at least that's how it behaves (latest Lazarus stable) on my side.

WriteLn is NOT a regular procedure. It's rather a special command for the compiler to replace it with the correct procedure call (which unfortunately you can't directly call without a hack).

View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-WriteLn-back-to-the-GUI-tp4033934p4033941.html Sent from the Free Pascal - Lazarus mailing list .
Hans-Peter Diettrich
to ListMember: I don't really want to alter the sources (which are more than 100 units). I'd rather find…
Show quoted text 5 lines
I'd rather find the unit where WriteLn() procedure is defined and alter it once and recompile FPC/Lazarus. But, I just can't locate where WriteLn procedure is defined. I did a grep (equivalent in Windows) but came up with nothing usable.

The Write... procedures are compiler magic, that's why you couldn't find the declarations.

A redirection should be possible by changing the Output variable, used when no FILE is given in an Write statement. At least it's so in Delphi, and there also existed instructions on how to write your own text file handler (for redirecting output to whatever target).

DoDi

Mark Morgan Lloyd
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 15 lines
ListMember schrieb: > I'd rather find the unit where WriteLn() procedure is defined and > alter it once and recompile FPC/Lazarus. > > But, I just can't locate where WriteLn procedure is defined. I did a > grep (equivalent in Windows) but came up with nothing usable. The Write... procedures are compiler magic, that's why you couldn't find the declarations. A redirection should be possible by changing the Output variable, used when no FILE is given in an Write statement. At least it's so in Delphi, and there also existed instructions on how to write your own text file handler (for redirecting output to whatever target).

This also takes us back to the point discussed a few weeks ago, which is that Lazarus doesn't really have a component optimised for line-by-line output and possibly input, i.e. wrapping a unix-style shell or a terminal emulator.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Sven Barth
to ListMember: I am trying to find where WriteLn is declared; but, apparently, WriteLn is among the…
ListMember wrote 11 lines
Hello, I am trying to find where WriteLn is declared; but, apparently, WriteLn is among the select few that Lazarus will ignore 'Find Declaration' requests --at least that's how it behaves (latest Lazarus stable) on my side. My ultimate goal, after finding where it is declared, is to locally modify that part of the sources so that (instead of writing to the console) it will use a global callback to display whatever WriteLn'ed in a TMemo.

Write(Ln), Read(Ln), WriteStr and ReadStr are compiler magic functions which are not available in Pascal source.

Or, is there already an alternative to redirect console output to the running GUI?

The Pascal IO mechanism relies on variables of type "file" or of type "text". For the latter you can specify your own "textdriver" with which you can replace the e.g. "Output" variable (which is used by "Write(Ln)" without a file argument) which can then redirect the output to something else. For an example of how to implement a text driver you can take a look at the "StreamIO" (
http://www.freepascal.org/docs-html/fcl/streamio/index.html ) unit provided with Free Pascal (in
$fpcdir/packages/fcl-base/src/streamio.pp). There a text driver is implemented which allows to "assign" streams to TextFile variables and thus to use Write(Ln)/Read(Ln) on them. You'll need to implement something similar for e.g. a memo (or whatever method you want to use to display the output).

Regards,
Sven

Sven Barth
to Sven Barth
Sven Barth wrote 29 lines
Am 23.10.2013 08:59, schrieb ListMember: > Hello, > > I am trying to find where WriteLn is declared; but, apparently, > WriteLn is among the select few that Lazarus will ignore 'Find > Declaration' requests --at least that's how it behaves (latest > Lazarus stable) on my side. > > My ultimate goal, after finding where it is declared, is to locally > modify that part of the sources so that (instead of writing to the > console) it will use a global callback to display whatever WriteLn'ed > in a TMemo. Write(Ln), Read(Ln), WriteStr and ReadStr are compiler magic functions which are not available in Pascal source. > Or, is there already an alternative to redirect console output to the > running GUI? The Pascal IO mechanism relies on variables of type "file" or of type "text". For the latter you can specify your own "textdriver" with which you can replace the e.g. "Output" variable (which is used by "Write(Ln)" without a file argument) which can then redirect the output to something else. For an example of how to implement a text driver you can take a look at the "StreamIO" ( http://www.freepascal.org/docs-html/fcl/streamio/index.html ) unit provided with Free Pascal (in $fpcdir/packages/fcl-base/src/streamio.pp). There a text driver is implemented which allows to "assign" streams to TextFile variables and thus to use Write(Ln)/Read(Ln) on them. You'll need to implement something similar for e.g. a memo (or whatever method you want to use to display the output).

And I just found an example which already does this for TCustomEdit descendants: http://kd5col.info/swag/DELPHI/0017.PAS.html I've not tested it in FPC, so maybe small adjustments might be necessary...

Regards,
Sven

Anton Kavalenka
to ListMember: I am trying to find where WriteLn is declared; but, apparently, WriteLn is among the…
ListMember wrote 20 lines
Hello, I am trying to find where WriteLn is declared; but, apparently, WriteLn is among the select few that Lazarus will ignore 'Find Declaration' requests --at least that's how it behaves (latest Lazarus stable) on my side. My ultimate goal, after finding where it is declared, is to locally modify that part of the sources so that (instead of writing to the console) it will use a global callback to display whatever WriteLn'ed in a TMemo. Or, is there already an alternative to redirect console output to the running GUI? -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

There was already a discussion on this maillist - try to search "[fpc-devel] StdOut capture for FPC RTL"
It is possible to create pipe, replace TextRec(output).Handle with pipe handle and rewrite() that output.
Gui thread just reads from the read end of the pipe and updates via Syncronize() whatever you want (memo, or even synedit). But you need to rewrite output for every thread you start later.

regards,
Anton
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131023/1fde1ba0/attachment.html>

ListMember
to Sven Barth: And I just found an example which already does this for TCustomEdit descendants:…
Sven Barth wrote 35 lines
Am 23.10.2013 17:06, schrieb Sven Barth: > Am 23.10.2013 08:59, schrieb ListMember: >> Hello, >> >> I am trying to find where WriteLn is declared; but, apparently, >> WriteLn is among the select few that Lazarus will ignore 'Find >> Declaration' requests --at least that's how it behaves (latest >> Lazarus stable) on my side. >> >> My ultimate goal, after finding where it is declared, is to locally >> modify that part of the sources so that (instead of writing to the >> console) it will use a global callback to display whatever >> WriteLn'ed in a TMemo. > Write(Ln), Read(Ln), WriteStr and ReadStr are compiler magic > functions which are not available in Pascal source. >> Or, is there already an alternative to redirect console output to >> the running GUI? > The Pascal IO mechanism relies on variables of type "file" or of type > "text". For the latter you can specify your own "textdriver" with > which you can replace the e.g. "Output" variable (which is used by > "Write(Ln)" without a file argument) which can then redirect the > output to something else. For an example of how to implement a text > driver you can take a look at the "StreamIO" ( > http://www.freepascal.org/docs-html/fcl/streamio/index.html ) unit > provided with Free Pascal (in > $fpcdir/packages/fcl-base/src/streamio.pp). There a text driver is > implemented which allows to "assign" streams to TextFile variables > and thus to use Write(Ln)/Read(Ln) on them. You'll need to implement > something similar for e.g. a memo (or whatever method you want to use > to display the output). And I just found an example which already does this for TCustomEdit descendants: http://kd5col.info/swag/DELPHI/0017.PAS.html I've not tested it in FPC, so maybe small adjustments might be necessary...

Wow.

This is far too (incredibly) elaborate.

It's a bit like giving me plans to set up an army to invade a country when all I want to do is to visit it as a tourist :)

As I mentioned in my first post, I am prepared to alter the compiler sources; and I had this in mind:

I would like to add these to a common unit --such as globals.pas

type
   TMyWriteLnCallback = procedure(AText: String);
var
   GMyWriteLnCallback: TMyCallback = nil;

and then, wherever the 'compiler magic' for WriteLn is, use something like

if Assigned(GMyWriteLnCallback) then GMyWriteLnCallback(TextStuff) else {do the usual console output}

So, could someone tell me where I have to inject these lines.

Michael Van Canneyt
to ListMember
ListMember wrote 12 lines
> And I just found an example which already does this for TCustomEdit > descendants: http://kd5col.info/swag/DELPHI/0017.PAS.html > I've not tested it in FPC, so maybe small adjustments might be necessary... Wow. This is far too (incredibly) elaborate. It's a bit like giving me plans to set up an army to invade a country when all I want to do is to visit it as a tourist :) As I mentioned in my first post, I am prepared to alter the compiler sources;

And this you consider not elaborate? That's a nice one :)

Show quoted text 16 lines
and I had this in mind: I would like to add these to a common unit --such as globals.pas type TMyWriteLnCallback = procedure(AText: String); var GMyWriteLnCallback: TMyCallback = nil; and then, wherever the 'compiler magic' for WriteLn is, use something like if Assigned(GMyWriteLnCallback) then GMyWriteLnCallback(TextStuff) else {do the usual console output} So, could someone tell me where I have to inject these lines.

As I wrote in my post: See the CRT unit.

It does exactly that. You need maybe 20 lines of code to do as you want.

Michael.

Sven Barth
to ListMember: Wow. This is far too (incredibly) elaborate. It's a bit like giving me plans to set up an…
ListMember wrote 43 lines
On 2013-10-23 18:10, Sven Barth wrote: > Am 23.10.2013 17:06, schrieb Sven Barth: >> Am 23.10.2013 08:59, schrieb ListMember: >>> Hello, >>> >>> I am trying to find where WriteLn is declared; but, apparently, >>> WriteLn is among the select few that Lazarus will ignore 'Find >>> Declaration' requests --at least that's how it behaves (latest >>> Lazarus stable) on my side. >>> >>> My ultimate goal, after finding where it is declared, is to locally >>> modify that part of the sources so that (instead of writing to the >>> console) it will use a global callback to display whatever >>> WriteLn'ed in a TMemo. >> Write(Ln), Read(Ln), WriteStr and ReadStr are compiler magic >> functions which are not available in Pascal source. >>> Or, is there already an alternative to redirect console output to >>> the running GUI? >> The Pascal IO mechanism relies on variables of type "file" or of >> type "text". For the latter you can specify your own "textdriver" >> with which you can replace the e.g. "Output" variable (which is used >> by "Write(Ln)" without a file argument) which can then redirect the >> output to something else. For an example of how to implement a text >> driver you can take a look at the "StreamIO" ( >> http://www.freepascal.org/docs-html/fcl/streamio/index.html ) unit >> provided with Free Pascal (in >> $fpcdir/packages/fcl-base/src/streamio.pp). There a text driver is >> implemented which allows to "assign" streams to TextFile variables >> and thus to use Write(Ln)/Read(Ln) on them. You'll need to implement >> something similar for e.g. a memo (or whatever method you want to >> use to display the output). > > And I just found an example which already does this for TCustomEdit > descendants: http://kd5col.info/swag/DELPHI/0017.PAS.html > I've not tested it in FPC, so maybe small adjustments might be > necessary... Wow. This is far too (incredibly) elaborate. It's a bit like giving me plans to set up an army to invade a country when all I want to do is to visit it as a tourist :)

No, this is the officially supported way to interfere with Pascal's IO system.

Show quoted text 5 lines
As I mentioned in my first post, I am prepared to alter the compiler sources; and I had this in mind: I would like to add these to a common unit --such as globals.pas

What would adding a callback to "globals.pas" provide? The string that is written by Writeln is created at runtime and not at compile time.

Show quoted text 14 lines
type TMyWriteLnCallback = procedure(AText: String); var GMyWriteLnCallback: TMyCallback = nil; and then, wherever the 'compiler magic' for WriteLn is, use something like if Assigned(GMyWriteLnCallback) then GMyWriteLnCallback(TextStuff) else {do the usual console output} So, could someone tell me where I have to inject these lines.

I've already written you how you can do it. Write a text driver which uses your callback function.

This is much easier than trying to understand how the compiler handles Writeln plus you don't need to manipulate the compiler or the RTL for that.

Regards,
Sven

leledumbo
to ListMember: Wow. This is far too (incredibly) elaborate. It's a bit like giving me plans to set up an…

If I understood correctly, you want to override the meaning of WriteLn (for programs and units using globals.pas), right? In that case, just create Write(Ln) procedure in globals unit. That will override the system unit one. However, you can't have the one with variable number of arguments, at least not in the system unit style one. Here's a compilable example:

{$mode objfpc} // you have to either in ObjFPC or Delphi mode for array of
const to work
var
  g: Boolean = true; // replace this with your callback variable
procedure WriteLn(args: array of const);
var
  i: Integer;
begin
  if not g then
    System.WriteLn('g')
  else begin
    for i := Low(args) to High(args) do
      case args[i].vtype of
        vtinteger    : System.Write(args[i].vinteger);
        vtboolean    : System.Write(args[i].vboolean);
        vtchar       : System.Write(args[i].vchar);
        vtextended   : System.Write(args[i].VExtended^);
        vtString     : System.Write(args[i].VString^);
        vtPointer    : System.Write(Longint(args[i].VPointer));
        vtPChar      : System.Write(args[i].VPChar);
        vtObject     : System.Write(args[i].VObject.Classname);
        vtClass      : System.Write(args[i].VClass.Classname);
        vtAnsiString : System.Write(AnsiString(args[i].VAnsiString));
        else           System.Write(args[i].vtype);
      end;
    System.WriteLn;
  end;
end;
begin
  WriteLn([1]); // yep, you need the angel bracket
  WriteLn([1,2]);
  WriteLn([1,3]);
  WriteLn(['this is ',3,' args']);
end.
View this message in context: http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-WriteLn-back-to-the-GUI-tp4033934p4033950.html Sent from the Free Pascal - Lazarus mailing list .
ListMember
to Michael Van Canneyt: And this you consider not elaborate? That's a nice one :) As I wrote in my post: See the…
Michael Van Canneyt wrote 18 lines
On Wed, 23 Oct 2013, ListMember wrote: >> And I just found an example which already does this for TCustomEdit >> descendants: http://kd5col.info/swag/DELPHI/0017.PAS.html >> I've not tested it in FPC, so maybe small adjustments might be >> necessary... > > Wow. > > This is far too (incredibly) elaborate. > > It's a bit like giving me plans to set up an army to invade a country > when all I want to do is to visit it as a tourist :) > > As I mentioned in my first post, I am prepared to alter the compiler > sources; And this you consider not elaborate? That's a nice one :)

:)

Actually, since this is FPC/Lazarus we're talking about (which means, thankfull NOT Delphi), you guys have made it relatively easy to re-compile both FPC and Lazarus.

And, since all I want to do is a very small surgical alteration, I'd say --given the above-- doing this is not elaborate at all.

As I wrote in my post: See the CRT unit. It does exactly that. You need maybe 20 lines of code to do as you want.

Will do, thanks.

But, let me ask this:

If I used the CRT unit, would I need to add it to every single unit in the project that uses WriteLn?

Marco van de Voort
to ListMember: I am trying to find where WriteLn is declared; but, apparently, WriteLn is among the…
ListMember wrote 5 lines
My ultimate goal, after finding where it is declared, is to locally modify that part of the sources so that (instead of writing to the console) it will use a global callback to display whatever WriteLn'ed in a TMemo.

There is no source of writeln, it is split up into various calls by the compiler. However in the end those writeln routines write a string, and that routine can be redirected.

Have a look at fpc/packages/streamio.pp

Running assignstream() on "output" would redirect all normal writeln output to the stream that is the second parameter.

Sven Barth
to ListMember: :) Actually, since this is FPC/Lazarus we're talking about (which means, thankfull NOT…
ListMember wrote 28 lines
On 2013-10-23 18:55, Michael Van Canneyt wrote: > On Wed, 23 Oct 2013, ListMember wrote: > >>> And I just found an example which already does this for TCustomEdit >>> descendants: http://kd5col.info/swag/DELPHI/0017.PAS.html >>> I've not tested it in FPC, so maybe small adjustments might be >>> necessary... >> >> Wow. >> >> This is far too (incredibly) elaborate. >> >> It's a bit like giving me plans to set up an army to invade a country >> when all I want to do is to visit it as a tourist :) >> >> As I mentioned in my first post, I am prepared to alter the compiler >> sources; > > And this you consider not elaborate? That's a nice one :) :) Actually, since this is FPC/Lazarus we're talking about (which means, thankfull NOT Delphi), you guys have made it relatively easy to re-compile both FPC and Lazarus. And, since all I want to do is a very small surgical alteration, I'd say --given the above-- doing this is not elaborate at all.

"Writeln" is a complex functionality. So you should better trust us (hint: I'm a compiler developer) when we say this is more difficult than you imagine.

Show quoted text 10 lines
> As I wrote in my post: See the CRT unit. > > It does exactly that. You need maybe 20 lines of code to do as you want. Will do, thanks. But, let me ask this: If I used the CRT unit, would I need to add it to every single unit in the project that uses WriteLn?

Michael did not say that you should use the CRT unit, but that the unit implements something similar and that you should take a look at it to implement your own variant of it.
And then you need to include your own unit only once (e.g. either you put the "hooking" into the initialization section or you do it at the start of your program)

Regards,
Sven

Sven Barth
to leledumbo: If I understood correctly, you want to override the meaning of WriteLn (for programs and…
leledumbo wrote 5 lines
If I understood correctly, you want to override the meaning of WriteLn (for programs and units using globals.pas), right? In that case, just create Write(Ln) procedure in globals unit. That will override the system unit one. However, you can't have the one with variable number of arguments, at least not in the system unit style one. Here's a compilable example:

I've understood it in such a way that he means
$fpc/compiler/globals.pas... Which would be the wrong way in multiple ways ^^

Regards,
Sven

Mark Morgan Lloyd
to ListMember: :) Actually, since this is FPC/Lazarus we're talking about (which means, thankfull NOT…
ListMember wrote 10 lines
> As I wrote in my post: See the CRT unit. > > It does exactly that. You need maybe 20 lines of code to do as you want. Will do, thanks. But, let me ask this: If I used the CRT unit, would I need to add it to every single unit in the project that uses WriteLn?

He didn't say *use* the CRT unit, he said *see* the CRT unit for a way to do it.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
ListMember
to Sven Barth: No, this is the officially supported way to interfere with Pascal's IO system. What would…
Sven Barth wrote 7 lines
Am 23.10.2013 17:50, schrieb ListMember: > This is far too (incredibly) elaborate. > > It's a bit like giving me plans to set up an army to invade a country > when all I want to do is to visit it as a tourist :) No, this is the officially supported way to interfere with Pascal's IO system.

I gathered as much. But, at least for me, writing a 'textdriver' simply to redirect the output of WriteLn is too complicated.

Show quoted text 7 lines
> As I mentioned in my first post, I am prepared to alter the compiler > sources; and I had this in mind: > > I would like to add these to a common unit --such as globals.pas What would adding a callback to "globals.pas" provide? The string that is written by Writeln is created at runtime and not at compile time.

And, that's precisely what I want to do: Get/redirect the string (that Writeln would write to console) back to my application in run time.

Show quoted text 20 lines
> > type > TMyWriteLnCallback = procedure(AText: String); > > var > GMyWriteLnCallback: TMyCallback = nil; > > and then, wherever the 'compiler magic' for WriteLn is, use something > like > > if Assigned(GMyWriteLnCallback) then GMyWriteLnCallback(TextStuff) > else {do the usual console output} > > So, could someone tell me where I have to inject these lines. I've already written you how you can do it. Write a text driver which uses your callback function. This is much easier than trying to understand how the compiler handles Writeln plus you don't need to manipulate the compiler or the RTL for that.

Frankly, I agree that I should not have to modify the compiler or the RTL; especially for something like redirecting the WriteLn output from console to my own application.

But, doing it through text drivers etc. is --how can I put it-- almost inhuman.

I don't want to do it through

Procedure AssignStream(var F: Textfile; Stream: TStream);

as it exists in StreamIO unit because I don't want to fiddle around with streams as it doesn't have an OnChange event. It means I need to wait for the whole app to finish, or I need to keep polling for what has changed in the stream. Totally useless in my case.

I could use the sample code you posted a link to (and, thank you also for that), and I adapted it to use TMemo for my use.

But, why would I have to write 100+ lines of code just to capture the output of WriteLn.

Plus, I keep getting segfaults when I close the application --something is calling InOutFunc when the app closes and still tries to write to a destroyed TMemo.

I think I'll go with Leledumbo's solution --and yes, will alter the globals.pas in the compiler's source.

ListMember
to Sven Barth: "Writeln" is a complex functionality. So you should better trust us (hint: I'm a compiler…
Sven Barth wrote
"Writeln" is a complex functionality. So you should better trust us (hint: I'm a compiler developer) when we say this is more difficult than you imagine.

I know you're a compiler developer; and, I have no intention of challenging you on that front --actually, I don't want to challenge anyone on any front at all, I have enough challenges as it is.

And, I am not trying to replace all of WriteLn functionality with my own code.

I am guessing, just guessing, FPC uses WriteLn to communicate with other modules (perhaps Lazarus too), but I also need its output directly in my app.

How about this:

Instead of redirecting all of its output through the callback, I only use callback to redirect a copy of its output --leaving the rest of its functionality intact?

Show quoted text 19 lines
>> As I wrote in my post: See the CRT unit. >> >> It does exactly that. You need maybe 20 lines of code to do as you >> want. > > Will do, thanks. > > But, let me ask this: > > If I used the CRT unit, would I need to add it to every single unit in > the project that uses WriteLn? Michael did not say that you should use the CRT unit, but that the unit implements something similar and that you should take a look at it to implement your own variant of it. And then you need to include your own unit only once (e.g. either you put the "hooking" into the initialization section or you do it at the start of your program)

I took a and AFAIC it is not significantly less complex than finding the place of WriteLn in compiler code and altering it to use a callback ;)

ListMember
to Marco van de Voort: There is no source of writeln, it is split up into various calls by the compiler. However…
Marco van de Voort wrote 13 lines
On Wed, Oct 23, 2013 at 09:59:04AM +0300, ListMember wrote: > My ultimate goal, after finding where it is declared, is to locally > modify that part of the sources so that (instead of writing to the > console) it will use a global callback to display whatever WriteLn'ed in > a TMemo. There is no source of writeln, it is split up into various calls by the compiler. However in the end those writeln routines write a string, and that routine can be redirected. Have a look at fpc/packages/streamio.pp Running assignstream() on "output" would redirect all normal writeln output to the stream that is the second parameter.

StreamIO isn't, unfortunately, good enough for me. I need to see WriteLn output in real-time, not when the application (or the called function) ends.

Luca Olivetti
to ListMember: I gathered as much. But, at least for me, writing a 'textdriver' simply to redirect the…

Al 23/10/13 21:01, En/na ListMember ha escrit:

Show quoted text 6 lines
I could use the sample code you posted a link to (and, thank you also for that), and I adapted it to use TMemo for my use. But, why would I have to write 100+ lines of code just to capture the output of WriteLn.

You already did that and it works, right? So what's the problem?

Plus, I keep getting segfaults when I close the application --something is calling InOutFunc when the app closes and still tries to write to a destroyed TMemo.

add a call to CloseFile(Output) to the form OnDestroy event.

Bye

Luca Olivetti Wetron Automation Technology http://www.wetron.es Tel. +34 935883004 Fax +34 935883007
Sven Barth
to ListMember: I gathered as much. But, at least for me, writing a 'textdriver' simply to redirect the…
ListMember wrote 27 lines
>> >> type >> TMyWriteLnCallback = procedure(AText: String); >> >> var >> GMyWriteLnCallback: TMyCallback = nil; >> >> and then, wherever the 'compiler magic' for WriteLn is, use something >> like >> >> if Assigned(GMyWriteLnCallback) then GMyWriteLnCallback(TextStuff) >> else {do the usual console output} >> >> So, could someone tell me where I have to inject these lines. > I've already written you how you can do it. Write a text driver which > uses your callback function. > > This is much easier than trying to understand how the compiler handles > Writeln plus you don't need to manipulate the compiler or the RTL for > that. Frankly, I agree that I should not have to modify the compiler or the RTL; especially for something like redirecting the WriteLn output from console to my own application. But, doing it through text drivers etc. is --how can I put it-- almost inhuman.

What is inhuman in using something that the language/runtime provides?

Show quoted text 11 lines
I don't want to do it through Procedure AssignStream(var F: Textfile; Stream: TStream); as it exists in StreamIO unit because I don't want to fiddle around with streams as it doesn't have an OnChange event. It means I need to wait for the whole app to finish, or I need to keep polling for what has changed in the stream. Totally useless in my case. I could use the sample code you posted a link to (and, thank you also for that), and I adapted it to use TMemo for my use.

I've attached my own version of EditText which I just adjusted. It works very similar to the original version I linked, but allows to use any TCustomEdit descendant (TMemo is one of them).

Show quoted text 6 lines
But, why would I have to write 100+ lines of code just to capture the output of WriteLn. Plus, I keep getting segfaults when I close the application --something is calling InOutFunc when the app closes and still tries to write to a destroyed TMemo.

You'll need to store the old value of "Output" and restore that before your form is destroyed.

I think I'll go with Leledumbo's solution --and yes, will alter the globals.pas in the compiler's source.

Adding a callback to globals.pas will be the completely wrong way...

Regards,
Sven
-------------- next part --------------
A non-text attachment was scrubbed...
Name: edittext.pas
Type: text/x-pascal
Size: 2233 bytes
Desc: not available
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131023/d6625bda/attachment.bin>

Sven Barth
to ListMember: I know you're a compiler developer; and, I have no intention of challenging you on that…
ListMember wrote 8 lines
On 2013-10-23 21:46, Sven Barth wrote: > "Writeln" is a complex functionality. So you should better trust us > (hint: I'm a compiler developer) when we say this is more difficult > than you imagine. I know you're a compiler developer; and, I have no intention of challenging you on that front --actually, I don't want to challenge anyone on any front at all, I have enough challenges as it is.

It's not about challenging someone. It's about you trying to do something for which the language/runtime already provides a solution for, but thereby using cannons to shoot down a bird...

Show quoted text 6 lines
And, I am not trying to replace all of WriteLn functionality with my own code. I am guessing, just guessing, FPC uses WriteLn to communicate with other modules (perhaps Lazarus too), but I also need its output directly in my app.

Let's maybe get a few things straight first: what are you trying to achieve in the end? Do you want to capture FPC's output or do you want to redirect the console output of your own application? If the first: Why don't you simply use the functionality of the OS to redirect the output to a file? Or do you start FPC from within your own application? In that case you could use the pipe mechanism of e.g. TProcess to capture the output (Lazarus does it the same way). If the second: use a text driver, modifying the compiler is not the answer.

Regards,
Sven

Hans-Peter Diettrich
to ListMember: I gathered as much. But, at least for me, writing a 'textdriver' simply to redirect the…
Show quoted text 6 lines
Frankly, I agree that I should not have to modify the compiler or the RTL; especially for something like redirecting the WriteLn output from console to my own application. But, doing it through text drivers etc. is --how can I put it-- almost inhuman.

It's basic OOP to derive classes from existing ones. Writing an text driver is exactly the same task, even if the "class" keyword is not used here - for historical reasons.

But, why would I have to write 100+ lines of code just to capture the output of WriteLn.

Then you're doing something very, very wrong.

Plus, I keep getting segfaults when I close the application --something is calling InOutFunc when the app closes and still tries to write to a destroyed TMemo.

No wonder. You should understand what you have to implement, before writing bogus code.

DoDi

ListMember
to Sven Barth: What is inhuman in using something that the language/runtime provides? I've attached my…
Sven Barth wrote
I've attached my own version of EditText which I just adjusted. It works very similar to the original version I linked, but allows to use any TCustomEdit descendant (TMemo is one of them).

Thank you.

But, I am still getting "exception class: 'External: SIGSEGV'" in here:

function EditWrite(var F: TTextRec): Integer; far;
begin
   with F do
   begin
     BufPtr^[BufPos] := #0;
PEditData(@F.UserData)^.Edit.SetSelTextBuf(PChar(BufPtr)); { <-- Here }
     BufPos := 0;
   end;
   EditWrite := 0;
end;
Show quoted text 9 lines
> But, why would I have to write 100+ lines of code just to capture the > output of WriteLn. > > Plus, I keep getting segfaults when I close the application --something > is calling InOutFunc when the app closes and still tries to write to a > destroyed TMemo. You'll need to store the old value of "Output" and restore that before your form is destroyed.

I tried it, but doesn't seem to work.

Here is the exact code I am using your modified code:

procedure TForm1.Button1Click(Sender: TObject);
begin
   try
     AssignEdit(System.Input, Memo1);
     Reset(System.Input);
     AssignEdit(System.Output, Memo2);
     Rewrite(System.Output);
     try
       DoPPExecute;
     except
       on E: Exception do begin
         Sleep(0);
       end;
     end;
   finally
     //CloseFile(System.Input);
     //CloseFile(System.Output);
   end;
end;

Uncommenting the closefile() stuff doesn't make any difference.

> I think I'll go with Leledumbo's solution --and yes, will alter the > globals.pas in the compiler's source. Adding a callback to globals.pas will be the completely wrong way...

I hear you, loud and clear :)

But, hearing you say that, doesn't mean I understand why it is so --especially when it does not help me :)

Could you please elaborate a little why it would the completely wrong way?

[this is from your other email in this thread]

Show quoted text 7 lines
Let's maybe get a few things straight first: what are you trying to achieve in the end? Do you want to capture FPC's output or do you want to redirect the console output of your own application? If the first: Why don't you simply use the functionality of the OS to redirect the output to a file? Or do you start FPC from within your own application? In that case you could use the pipe mechanism of e.g. TProcess to capture the output (Lazarus does it the same way).

Here is what I have done:

I have copied all the stuff in the 'compiler' folder somewhere else and altered the pp.lpi into pp.pas and made it part of my DemoProject.lpi.

I have renamed the main proc in pp.lpi to be DoPPExecute.

It builds and compiles fine.

It also runs, sort of fine.

Except that, those WriteLn stuff doesn't because it's no more a console app.

This is the point I need to solve that WriteLn headache.

Honestly, I was preapred for any other issue, but I never expected WriteLn to such a sacred cow that I need to perform such elaborate rituals to workaround it --even then it doesn't seem to work so far.

ListMember
to Hans-Peter Diettrich: It's basic OOP to derive classes from existing ones. Writing an text driver is exactly…
Hans-Peter Diettrich wrote 12 lines
ListMember schrieb: > Frankly, I agree that I should not have to modify the compiler or the > RTL; especially for something like redirecting the WriteLn output > from console to my own application. > > But, doing it through text drivers etc. is --how can I put it-- > almost inhuman. It's basic OOP to derive classes from existing ones. Writing an text driver is exactly the same task, even if the "class" keyword is not used here - for historical reasons.

Thank you for that gem.

> But, why would I have to write 100+ lines of code just to capture the > output of WriteLn. Then you're doing something very, very wrong.

Have you looked at the code Sven linked to, or are you saying this just because it is the usual thing to say under these circumstances?

Show quoted text 6 lines
> Plus, I keep getting segfaults when I close the application > --something is calling InOutFunc when the app closes and still tries > to write to a destroyed TMemo. No wonder. You should understand what you have to implement, before writing bogus code.

Again, rather than the high horse you seem to be riding (which even Sven doesn't, despite the fact that he is a compiler developer), thereby adding nothing of value to the solution of the problem, I'd appreciate it very much if you could offer focused help.

Hans-Peter Diettrich
to ListMember
Show quoted text 23 lines
On 2013-10-23 23:20, Hans-Peter Diettrich wrote: > ListMember schrieb: > >> Frankly, I agree that I should not have to modify the compiler or the >> RTL; especially for something like redirecting the WriteLn output >> from console to my own application. >> >> But, doing it through text drivers etc. is --how can I put it-- >> almost inhuman. > > It's basic OOP to derive classes from existing ones. Writing an text > driver is exactly the same task, even if the "class" keyword is not > used here - for historical reasons. Thank you for that gem. >> But, why would I have to write 100+ lines of code just to capture the >> output of WriteLn. > > Then you're doing something very, very wrong. Have you looked at the code Sven linked to, or are you saying this just because it is the usual thing to say under these circumstances?

Writing an text driver was about my first project in D4, all I can contribute is from that time and environment.

Show quoted text 11 lines
>> Plus, I keep getting segfaults when I close the application >> --something is calling InOutFunc when the app closes and still tries >> to write to a destroyed TMemo. > > No wonder. You should understand what you have to implement, before > writing bogus code. Again, rather than the high horse you seem to be riding (which even Sven doesn't, despite the fact that he is a compiler developer), thereby adding nothing of value to the solution of the problem, I'd appreciate it very much if you could offer focused help.

Sorry, my bad :-(

I'd suggest that you write an file driver first, to get familiar with the functions to implement. Play around using an file buffer, or with direct file I/O. Then it should be easier to replace the file by another (GUI) component, in the next step. If you have problems with that code, you can look up the RTL implementation of such I/O.

Next comes a decision of direct (write-through) or buffered output. When the output goes into a Memo like control, I'd simply append all output immediately to memo.Text. AFAIR I ended up using a TStrings object, as obtainable from e.g. a ListBox, and implemented line buffering capabilities. In this case only full lines (up to EOL, or when the buffer is filled entirely) are added to the TStrings object and removed from the buffer.

Bidirectional (console-like?) I/O deserves more considerations, if you want to implement something like that.

DoDi

Graeme Geldenhuys
ListMember wrote 8 lines
> > As I wrote in my post: See the CRT unit. > > It does exactly that. You need maybe 20 lines of code to do as you > want. If I used the CRT unit, would I need to add it to every single unit in the project that uses WriteLn?

Please read the replies in more detail. Michael said "see the CRT unit" *not* "use the CRT unit"!

G.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131024/87eb6ecf/attachment.html>

Sven Barth
to ListMember: Thank you. But, I am still getting "exception class: 'External: SIGSEGV'" in here:…
ListMember wrote 58 lines
On 2013-10-23 22:36, Sven Barth wrote: > I've attached my own version of EditText which I just adjusted. It > works very similar to the original version I linked, but allows to > use any TCustomEdit descendant (TMemo is one of them). > Thank you. But, I am still getting "exception class: 'External: SIGSEGV'" in here: function EditWrite(var F: TTextRec): Integer; far; begin with F do begin BufPtr^[BufPos] := #0; PEditData(@F.UserData)^.Edit.SetSelTextBuf(PChar(BufPtr)); { <-- Here } BufPos := 0; end; EditWrite := 0; end; >> But, why would I have to write 100+ lines of code just to capture the >> output of WriteLn. >> >> Plus, I keep getting segfaults when I close the application --something >> is calling InOutFunc when the app closes and still tries to write to a >> destroyed TMemo. > > You'll need to store the old value of "Output" and restore that > before your form is destroyed. I tried it, but doesn't seem to work. Here is the exact code I am using your modified code: procedure TForm1.Button1Click(Sender: TObject); begin try AssignEdit(System.Input, Memo1); Reset(System.Input); AssignEdit(System.Output, Memo2); Rewrite(System.Output); try DoPPExecute; except on E: Exception do begin Sleep(0); end; end; finally //CloseFile(System.Input); //CloseFile(System.Output); end; end; Uncommenting the closefile() stuff doesn't make any difference.

Did you read (and understand) what I wrote? You need to "store the old value of "Output" and restore" it afterwards. This means for your button click event:

=== code begin ===

procedure TForm1.Button1Click(Sender: TObject);
var
   oldoutput, oldinput: TextFile;
begin
   oldinput := System.Input;
   oldoutput := System.Output;
   (* the assigns should be done before the try so that Input and Output
have the correct values *)
   AssignEdit(System.Input, Memo1);
AssignEdit(System.Output, Memo2);
   try
     Reset(System.Input);
     Rewrite(System.Output);
     try
       DoPPExecute;
     except
       on E: Exception do begin
         Sleep(0);
       end;
     end;
   finally
     (* using CloseFile will ensure that all pending output is flushed *)
     CloseFile(System.Input);
     CloseFile(System.Output);
     System.Input := oldinput;
     System.Output := oldoutput;
   end;
end;

=== code end ===

This will work, I've tested it myself (though not with the compiler).

Show quoted text 13 lines
>> I think I'll go with Leledumbo's solution --and yes, will alter the >> globals.pas in the compiler's source. > > Adding a callback to globals.pas will be the completely wrong way... I hear you, loud and clear :) But, hearing you say that, doesn't mean I understand why it is so --especially when it does not help me :) Could you please elaborate a little why it would the completely wrong way?

"Writeln" is a procedure implemented by the compiler, but not in form of a function inside the compiler's source. If the compiler (in your case the compiler you compile the compiler with) encounters a "Writeln" it will parse its arguments and build up a more complex code sequence which will convert each argument to a string which is passed into the specified file ("Output" by default). So modifying "Writeln" inside the compiler's source that you use in your own program would only work for code that you'd compile with that compiler and then your callback function would be nonsense, because that callback would be at compile time and not at runtime.

Show quoted text 31 lines
[this is from your other email in this thread] > Let's maybe get a few things straight first: what are you trying to > achieve in the end? Do you want to capture FPC's output or do you > want to redirect the console output of your own application? > If the first: Why don't you simply use the functionality of the OS to > redirect the output to a file? Or do you start FPC from within your > own application? In that case you could use the pipe mechanism of > e.g. TProcess to capture the output (Lazarus does it the same way). Here is what I have done: I have copied all the stuff in the 'compiler' folder somewhere else and altered the pp.lpi into pp.pas and made it part of my DemoProject.lpi. I have renamed the main proc in pp.lpi to be DoPPExecute. It builds and compiles fine. It also runs, sort of fine. Except that, those WriteLn stuff doesn't because it's no more a console app. This is the point I need to solve that WriteLn headache. Honestly, I was preapred for any other issue, but I never expected WriteLn to such a sacred cow that I need to perform such elaborate rituals to workaround it --even then it doesn't seem to work so far.

There aren't many issues, because the compiler is also compiled into the textmode IDE fp. Please note however that there might be memory leaks in case of compilation errors. Also you should take note that using a development version of the compiler (in this case 2.7.1) which is compiled by a release compiler with the release RTL (in this case 2.6.2 I assume) *might* result in different results than if you compile the compiler with a 2.7.1 RTL. So I'd suggest you to completely build a 2.7.1 compiler and than use that compiler together with its RTL to compile your own application which in turn uses the same compiler source.

And with that in mind I can also present you with another possible solution (though the text mode driver will do it's job correctly): the compiler unit "comphook" contains a few callbacks which are used by the textmode IDE to capture the compiler's output and a few further things. You can take a look at $fpc\ide\fpcompil.pas to see what you should/could do inside those callbacks (they are assigned at around line 943).

Regards,
Sven

Hans-Peter Diettrich
to Sven Barth
Am 23.10.2013 23:08, schrieb ListMember: Did you read (and understand) what I wrote? You need to "store the old value of "Output" and restore" it afterwards.

IMO it's not a good idea to change Input and Output on the fly. Problems can result e.g. from unprocessed characters hanging in the buffers.

Even for testing purposes I'd suggest to use explicit files in the Read/Write statements.

DoDi

Sven Barth
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 12 lines
Sven Barth schrieb: > Am 23.10.2013 23:08, schrieb ListMember: > Did you read (and understand) what I wrote? You need to "store the > old value of "Output" and restore" it afterwards. IMO it's not a good idea to change Input and Output on the fly. Problems can result e.g. from unprocessed characters hanging in the buffers. Even for testing purposes I'd suggest to use explicit files in the Read/Write statements.

The buffer is part of the Input/Output variable. So if you change one of them the content of the buffer will still be there, but simply not processed. You could always do a "FlushFile(Output)" to clear the buffer before changing it however. I see no problem here.

Regards,
Sven

Lukasz Sokol
to ListMember: StreamIO isn't, unfortunately, good enough for me. I need to see WriteLn output in…
ListMember wrote 19 lines
On 2013-10-23 21:11, Marco van de Voort wrote: > On Wed, Oct 23, 2013 at 09:59:04AM +0300, ListMember wrote: >> My ultimate goal, after finding where it is declared, is to >> locally modify that part of the sources so that (instead of >> writing to the console) it will use a global callback to display >> whatever WriteLn'ed in a TMemo. > There is no source of writeln, it is split up into various calls by > the compiler. However in the end those writeln routines write a > string, and that routine can be redirected. > > Have a look at fpc/packages/streamio.pp > > Running assignstream() on "output" would redirect all normal > writeln output to the stream that is the second parameter. StreamIO isn't, unfortunately, good enough for me. I need to see WriteLn output in real-time, not when the application (or the called function) ends.

Aside from other ( better) ideas I've seen in this thread :

why not create a TThread hanging on the output pipe, checking it periodically, (or maybe hooking it to some signal that maybe is passed when stream is written to?) NOT interfering with GUI, but then signalling / passing the content to the main thread in a 'OnWriteln' event manner ? You'd have to have this thread copy the output stream to a buffer anyway, and then passing it to main thread, probably copy it again.

Because if your application is single-threaded (GUI thread only) or have other threads around that use writeln(), your OnWriteln 'event' in the GUI won't happen until the GUI thread is ready to handle it anyway (hits the Idle loop) (because it only has one context, yes LCL is single threaded) so there is not much 'real time' here that you can assume.

-L

ListMember
to Hans-Peter Diettrich: Writing an text driver was about my first project in D4, all I can contribute is from…
Hans-Peter Diettrich wrote 16 lines
I'd suggest that you write an file driver first, to get familiar with the functions to implement. Play around using an file buffer, or with direct file I/O. Then it should be easier to replace the file by another (GUI) component, in the next step. If you have problems with that code, you can look up the RTL implementation of such I/O. Next comes a decision of direct (write-through) or buffered output. When the output goes into a Memo like control, I'd simply append all output immediately to memo.Text. AFAIR I ended up using a TStrings object, as obtainable from e.g. a ListBox, and implemented line buffering capabilities. In this case only full lines (up to EOL, or when the buffer is filled entirely) are added to the TStrings object and removed from the buffer. Bidirectional (console-like?) I/O deserves more considerations, if you want to implement something like that.

<rant>
I am sure what you've described does make sense, but I wonder if you ever stood back to see that all of it appears much like a recommendation to use smoke signalling techniques (or hire someone proficient) just because one wants to communicate _today_ with a person of indigeneous ancestry.
</rant>

What is worse, and what makes this rant almost absolutely pointless, is the fact that you're not responsible for any of it.

ListMember
to Sven Barth: Did you read (and understand) what I wrote? You need to "store the old value of "Output"…
Sven Barth wrote
Did you read (and understand) what I wrote?

I did, of course, read; but, apparently, I didn't understand it the way you meant.

Sorry.

You need to "store the old value of "Output" and restore" it afterwards. This means for your button click event:

Got it now. Thank you.

Show quoted text 5 lines
And with that in mind I can also present you with another possible solution (though the text mode driver will do it's job correctly): the compiler unit "comphook" contains a few callbacks which are used by the textmode IDE to capture the compiler's output and a few further things.

Actually, it was the def_comment() function in comphook.pas that started all this.

You can take a look at $fpc\ide\fpcompil.pas to see what you should/could do inside those callbacks (they are assigned at around line 943).

Thank you. This is a lot more like what I need.

Sven Barth
to ListMember
ListMember wrote 27 lines
On 2013-10-24 10:46, Sven Barth wrote: > Did you read (and understand) what I wrote? I did, of course, read; but, apparently, I didn't understand it the way you meant. Sorry. > You need to "store the old value of "Output" and restore" it > afterwards. This means for your button click event: Got it now. Thank you. > And with that in mind I can also present you with another possible > solution (though the text mode driver will do it's job correctly): the > compiler unit "comphook" contains a few callbacks which are used by > the textmode IDE to capture the compiler's output and a few further > things. Actually, it was the def_comment() function in comphook.pas that started all this. > You can take a look at $fpc\ide\fpcompil.pas to see what you > should/could do inside those callbacks (they are assigned at around > line 943). Thank you. This is a lot more like what I need.

And if you'd now be so kind to explain please why you compile the compiler into your application? (I'm just curious ^^)

Regards,
Sven

ListMember
to Sven Barth
Sven Barth wrote
And if you'd now be so kind to explain please why you compile the compiler into your application? (I'm just curious ^^)

Curiousity, really.

And, there are several.

First, I wanted to see if it's possible/hard to work with compiler sources under Lazarus.

The reason I wanted to see that is basically because I have long lost the skill/patience to work with code in text mode --actually, I have come to abhor it altogether; probably because of the memories of intense claustrophobia it brings back.

Now that I seem to have passed that hurdle, I'd like to experiment with it --time permitting.

One of my aims (one which we discussed here a few years ago) is to rip the parser and lexer from the compiler. I want to have a token tree (including directives) from the mouth of the horse (so to speak).

I also want to see how hard it is to turn the compiler into a module of the frontend (see my text mode hatred) by getting rid of commandline switches (and also of textmode feedback).

Actually, I am surprised that no one (that I know of) has done this yet.

After all, both FPC and all the IDEs (Lazarus, fpGUI, MSEide+MSEgui etc.) use FPC but the degree of integration between them is lacking, IMO.

I want to see how hard it is to bring them a little closer.

As my little adventure with WriteLn show, it probably isn't very easy.

That alone is sufficient to make me well aware that these are quite grand targets, but I want to take stab all the same.

I have no grand schemes such as asking anyone to even consider incorporating my modifications (if I manage to produce any) into codebases of any of the above projects as I am well aware how taxing/impossible that sort of an endavor would be.

Anyway, if nothing else, it will be a great learning experience.

I love frustration :)

Hans-Peter Diettrich
to ListMember
Show quoted text 9 lines
One of my aims (one which we discussed here a few years ago) is to rip the parser and lexer from the compiler. I want to have a token tree (including directives) from the mouth of the horse (so to speak). I also want to see how hard it is to turn the compiler into a module of the frontend (see my text mode hatred) by getting rid of commandline switches (and also of textmode feedback). Actually, I am surprised that no one (that I know of) has done this yet.

I already tried what you describe. All I could finish was an Oberon front end, and a working preprocessor.

FPC is a production compiler by design, i.e. a mess of optimized spaghetti code, with values copied frequently between records and global variables. You can get token trees from the subroutines' code, if this is sufficient. Declarations are parsed directly into dedicated data structures.

After all, both FPC and all the IDEs (Lazarus, fpGUI, MSEide+MSEgui etc.) use FPC but the degree of integration between them is lacking, IMO. I want to see how hard it is to bring them a little closer.

You won't get any assistance by the FPC developers, all you can do is tweaking a copy of the compiler code.

I love frustration :)

Odds are good :-(

DoDi

Sven Barth
to ListMember: Curiousity, really. And, there are several. First, I wanted to see if it's possible/hard…
ListMember wrote
First, I wanted to see if it's possible/hard to work with compiler sources under Lazarus.

Considerung that some compiler developers (including me) use Lazarus for development on FPC: yes, it's definitely possible. Especially debugging and code completion are very handy here :)

One of my aims (one which we discussed here a few years ago) is to rip the parser and lexer from the compiler. I want to have a token tree (including directives) from the mouth of the horse (so to speak).

That will be quite complicated, because the scanner will not output the directives it parsed (e.g. if you do a "consume(_SEMICOLON)" to parse a ";" any directive between your current position and the next ";" will be handled and the parser will not be notified of any changes (as a result of these directives there might be changes in settings variables or defines however). Also the tree is not really possible to get a hold of, because a node (e.g. a fornode for a for-in) might be immediately replaced by a whilenode thus you'll never see that there was a for-in. Additionally the parser is not geared towards handling erratic code. There are quite some places where error recovery is tried so that errors further down can be displayed, but in essence the parser is very bad in handling erratic code.

I also want to see how hard it is to turn the compiler into a module of the frontend (see my text mode hatred) by getting rid of commandline switches (and also of textmode feedback).

Here I'd suggest you to look at the code of the text mode IDE again. It compiles the compiler itself and passes its own options set in the FreeVision TUI to the compiler.

Actually, I am surprised that no one (that I know of) has done this yet.

The text mode IDE is doing it...

After all, both FPC and all the IDEs (Lazarus, fpGUI, MSEide+MSEgui etc.) use FPC but the degree of integration between them is lacking, IMO.

Because by the way it currently is you can easily switch the compiler version and the compiler target. Each compiled compiler can only compile for one architecture (but each supported OS of that architecture), so how would you implement cross platform compilation then?

Anyway, if nothing else, it will be a great learning experience.

Agreed.

I love frustration :)

I noticed ^^

Regards,
Sven

ListMember
to Sven Barth
Sven Barth wrote 10 lines
Am 25.10.2013 01:06, schrieb ListMember: > One of my aims (one which we discussed here a few years ago) is to > rip the parser and lexer from the compiler. I want to have a token > tree (including directives) from the mouth of the horse (so to speak). That will be quite complicated, because the scanner will not output the directives it parsed (e.g. if you do a "consume(_SEMICOLON)" to parse a ";" any directive between your current position and the next ";" will be handled and the parser will not be notified of any changes (as a result of these directives there might be changes in settings variables or defines however).

Unless there's a lot more deeper magic than I can fathom, I am guessing the parser is parsing the directives if only to ignore code in that directive block.

If this is so (is it?), can't I inject/override some code in there to emit a token for the directive as well as make it also parse the blocks it normally would ignore?

Also the tree is not really possible to get a hold of, because a node (e.g. a fornode for a for-in) might be immediately replaced by a whilenode thus you'll never see that there was a for-in.

So, I will need to catch things before they get optimized/transformed into something else.. I love these tricks/traps.. :)

Additionally the parser is not geared towards handling erratic code. There are quite some places where error recovery is tried so that errors further down can be displayed, but in essence the parser is very bad in handling erratic code.

Frankly, I too am not interested in uncompilable code; so I won't mind if it throws in the towel before attempting to scan everything until the bitter end.

But, yes, all these shortcuts/pitfalls (for what I want to do) are quite discouraging, yet the flip-side means any alternative independent of FPC will always be lacking.

Show quoted text 6 lines
> I also want to see how hard it is to turn the compiler into a module > of the frontend (see my text mode hatred) by getting rid of > commandline switches (and also of textmode feedback). Here I'd suggest you to look at the code of the text mode IDE again. It compiles the compiler itself and passes its own options set in the FreeVision TUI to the compiler.

Thank you. I am hoping I will get to that in good time.

> > Actually, I am surprised that no one (that I know of) has done this yet. The text mode IDE is doing it...

I meant the GUI ones.

Show quoted text 8 lines
> After all, both FPC and all the IDEs (Lazarus, fpGUI, MSEide+MSEgui > etc.) use FPC but the degree of integration between them is lacking, > IMO. Because by the way it currently is you can easily switch the compiler version and the compiler target. Each compiled compiler can only compile for one architecture (but each supported OS of that architecture), so how would you implement cross platform compilation then?

Couldn't it be done through DLLs?

I mean, compile the compiler into a dll where the name is an easily format that tells (say) Lazarus what version it is, and its native and target platforms are.

At that point, it would need a stable (yet an extendable) API, but it seems it is doable.

[This, if it works, does not preclude a standalone compiler; a shim-like exe simply uses one of those DLLs.]

Or, have I just reinforced the assertion that ignorance is bliss? ;)

ListMember
to Hans-Peter Diettrich: I already tried what you describe. All I could finish was an Oberon front end, and a…
Hans-Peter Diettrich wrote
You won't get any assistance by the FPC developers, all you can do is tweaking a copy of the compiler code.

I have gathered as much --though, not through first hand experience, thankfully; but, through witnessing others get burnt ;(

And, even though it took me quite sometime to do so, I have come round to accepting that.

I mean, since we (that is, everyone else, other that the compiler devs) expect them to throw us (over the wall) working code without us actually helping them in any direct way (other than bug reports, which are indirect and after the fact), why shouldn't they expect working code from people suggesting (semi-) major code overhaul.

While that does not mean I like it one bit, it is fair enough; and, I have to lump it. Such is life.

Sven Barth
to ListMember: Unless there's a lot more deeper magic than I can fathom, I am guessing the parser is…
"ListMember" wrote 6 lines
On 2013-10-25 10:53, Sven Barth wrote: > > Am 25.10.2013 01:06, schrieb ListMember: >> >> One of my aims (one which we discussed here a few years ago) is to rip

the parser and lexer from the compiler. I want to have a token tree (including directives) from the mouth of the horse (so to speak).

> > That will be quite complicated, because the scanner will not output the

directives it parsed (e.g. if you do a "consume(_SEMICOLON)" to parse a ";" any directive between your current position and the next ";" will be handled and the parser will not be notified of any changes (as a result of these directives there might be changes in settings variables or defines however).

Unless there's a lot more deeper magic than I can fathom, I am guessing

the parser is parsing the directives if only to ignore code in that directive block.

If this is so (is it?), can't I inject/override some code in there to

emit a token for the directive as well as make it also parse the blocks it normally would ignore?

No, the parser will never see those. After all that's one purpose of ifdefs: to keep the parser from reading things that is couldn't possibly parse. Directives are completely handled by the scanner.

> Also the tree is not really possible to get a hold of, because a node

(e.g. a fornode for a for-in) might be immediately replaced by a whilenode thus you'll never see that there was a for-in.

So, I will need to catch things before they get optimized/transformed

into something else.. I love these tricks/traps.. :)

This often happens inside the typecheck passes whereby the following code might do things dependant on that result.

But, yes, all these shortcuts/pitfalls (for what I want to do) are quite

discouraging, yet the flip-side means any alternative independent of FPC will always be lacking.

In my opinion that energy is better put into getting e.g. fcl-passrc up to date and keep it that way (so that at least each release can handle code that the compiler also accepts).

>> After all, both FPC and all the IDEs (Lazarus, fpGUI, MSEide+MSEgui

etc.) use FPC but the degree of integration between them is lacking, IMO.

> > Because by the way it currently is you can easily switch the compiler

version and the compiler target. Each compiled compiler can only compile for one architecture (but each supported OS of that architecture), so how would you implement cross platform compilation then?

Show quoted text 5 lines
Couldn't it be done through DLLs? I mean, compile the compiler into a dll where the name is an easily

format that tells (say) Lazarus what version it is, and its native and target platforms are.

At that point, it would need a stable (yet an extendable) API, but it

seems it is doable.

[This, if it works, does not preclude a standalone compiler; a shim-like

exe simply uses one of those DLLs.]

Or, have I just reinforced the assertion that ignorance is bliss? ;)

I already had the idea with DLLs once myself.
As long as the interface for exchanging options (and maybe also unit locations ;) )is kept stable or at least backwards compatible this should work. And as long as the heaps are kept seperate unloading a compiler library should also solve the problem with memory leaks... (maybe add a function to the API to get the current heap state ^^)

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131025/875c9cb0/attachment.html>

Lukasz Sokol
to ListMember: I have gathered as much --though, not through first hand experience, thankfully; but,…

On 25/10/13 12:06, ListMember wrote:
[...]

Show quoted text 6 lines
I mean, since we (that is, everyone else, other that the compiler devs) expect them to throw us (over the wall) working code without us actually helping them in any direct way (other than bug reports, which are indirect and after the fact), why shouldn't they expect working code from people suggesting (semi-) major code overhaul.

Let me guess fpc devs reaction:

patches are welcome as long as you're prepared to write and support them

:)

(well that's Pascal-verbose, because on lkml you'd probably get just -ENOPATCH
...)

While that does not mean I like it one bit, it is fair enough; and, I have to lump it. Such is life.

-L

Sven Barth
to Lukasz Sokol
"Lukasz Sokol" wrote 14 lines
On 25/10/13 12:06, ListMember wrote: [...] > I mean, since we (that is, everyone else, other that the compiler > devs) expect them to throw us (over the wall) working code without us > actually helping them in any direct way (other than bug reports, > which are indirect and after the fact), why shouldn't they expect > working code from people suggesting (semi-) major code overhaul. > Let me guess fpc devs reaction: patches are welcome as long as you're prepared to write and support them :)

Depends. If it dramatically changes the compiler there must be really valid reasons and "betterintegrate with IDEs" is not necessarily one...

(well that's Pascal-verbose, because on lkml you'd probably get just -ENOPATCH ...)

Hahaha! That's a good one :D

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131025/0ddd1f9a/attachment.html>

ListMember
to Sven Barth: the parser and lexer from the compiler. I want to have a token tree (including…
Sven Barth wrote
In my opinion that energy is better put into getting e.g. fcl-passrc up to date and keep it that way (so that at least each release can handle code that the compiler also accepts).

You're, of course, right.

But, never mind the question of which part of what team will maintain it (and what triggers a maintenance request, other than a long after-the-fact bug report), how do you make sure that --at any moment in time-- fcl-passrc is up-to-date?

I mean, suppose --using fcl-passrc-- we went through all the publicly available code (repositories of FPC, Lazarus, etc.) and it reported no errors, would it prove/guarantee that fcl-passrc is up-to-date?

If we could say that with enouh conjfidence, I'd gladly shift my focus to fcl-passrc.

Show quoted text 8 lines
I already had the idea with DLLs once myself. As long as the interface for exchanging options (and maybe also unit locations ;) )is kept stable or at least backwards compatible this should work. And as long as the heaps are kept seperate unloading a compiler library should also solve the problem with memory leaks... (maybe add a function to the API to get the current heap state ^^)

Naturally <g> I know nothing about the importance of heap especially in this context or probbaly in any relevant context.

How hard would it be?

BTree Computing Services
to ListMember

In the Lazarus GUI, when components are placed on a form, vertical and horizontal design guidelines are drawn to assist in aligning the component relative to other components. These lines are like 'laser lines' that shoot out from the edges. Does anyone know how that technique is done or the source code so that I can implement a similar technique in my app?

Thanks

Sven Barth
to ListMember: You're, of course, right. But, never mind the question of which part of what team will…
"ListMember" wrote
On 2013-10-25 14:53, Sven Barth wrote: > In my opinion that energy is better put into getting e.g. fcl-passrc up

to date and keep it that way (so that at least each release can handle code that the compiler also accepts).

Show quoted text 5 lines
You're, of course, right. But, never mind the question of which part of what team will maintain it

(and what triggers a maintenance request, other than a long after-the-fact bug report), how do you make sure that --at any moment in time-- fcl-passrc is up-to-date?

The main

I mean, suppose --using fcl-passrc-- we went through all the publicly

available code (repositories of FPC, Lazarus, etc.) and it reported no errors, would it prove/guarantee that fcl-passrc is up-to-date?

If we could say that with enouh conjfidence, I'd gladly shift my focus to

fcl-passrc.

Show quoted text 5 lines
> I already had the idea with DLLs once myself. > > As long as the interface for exchanging options (and maybe also unit

locations ;) )is kept stable or at least backwards compatible this should work. And as long as the heaps are kept seperate unloading a compiler library should also solve the problem with memory leaks... (maybe add a function to the API to get the current heap state ^^)

> Naturally <g> I know nothing about the importance of heap especially in

this context or probbaly in any relevant context.

Show quoted text 9 lines
How hard would it be? -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131026/6a00ea21/attachment-0001.html>

Sven Barth
to ListMember: You're, of course, right. But, never mind the question of which part of what team will…

Sorry, pressed Send by accident... -.*

"ListMember" wrote
On 2013-10-25 14:53, Sven Barth wrote: > In my opinion that energy is better put into getting e.g. fcl-passrc up

to date and keep it that way (so that at least each release can handle code that the compiler also accepts).

Show quoted text 5 lines
You're, of course, right. But, never mind the question of which part of what team will maintain it

(and what triggers a maintenance request, other than a long after-the-fact bug report), how do you make sure that --at any moment in time-- fcl-passrc is up-to-date?

I mean, suppose --using fcl-passrc-- we went through all the publicly

available code (repositories of FPC, Lazarus, etc.) and it reported no errors, would it prove/guarantee that fcl-passrc is up-to-date?

If we could say that with enouh conjfidence, I'd gladly shift my focus to

fcl-passrc.

The main tests for what FPC supports and what not is for one compiling (or in this context at least "parsing") the compiler's source, the RTL and the packages. Additionally there are the tests which should either succeed or dail to compile/run (and when a new feature is added at least one test is added). So in my opinion the ability to correctly parse compiler, RTL and packages sources plus correctly parsing all tests that should compile and failing all tests that should fail would be enough in my opinion.

The main maintenance would be by the FPC team, but patches are welcome and if someone (e.g. you) "proves worthy" he can get SVN write to the fcl-passrc directory.

> I already had the idea with DLLs once myself. > > As long as the interface for exchanging options (and maybe also unit

locations ;) )is kept stable or at least backwards compatible this should work. And as long as the heaps are kept seperate unloading a compiler library should also solve the problem with memory leaks... (maybe add a function to the API to get the current heap state ^^)

> Naturally <g> I know nothing about the importance of heap especially in

this context or probbaly in any relevant context.

How hard would it be?

As non-shared heap is the default, this would be no problem ^^

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131026/9bc13859/attachment.html>

ListMember
to Sven Barth
Sven Barth wrote 12 lines
> If we could say that with enouh conjfidence, I'd gladly shift my focus to fcl-passrc. The main tests for what FPC supports and what not is for one compiling (or in this context at least "parsing") the compiler's source, the RTL and the packages. Additionally there are the tests which should either succeed or dail to compile/run (and when a new feature is added at least one test is added). So in my opinion the ability to correctly parse compiler, RTL and packages sources plus correctly parsing all tests that should compile and failing all tests that should fail would be enough in my opinion.

OK, then. I'll take a look at that one. Thanks.

Show quoted text 7 lines
> Naturally <g> I know nothing about the importance of heap especially in this context or probbaly in any relevant context. > How hard would it be? As non-shared heap is the default, this would be no problem ^^

I am having difficulty interpreting '^^'.
What is it meant to mean?

Sven Barth
to ListMember
"ListMember" wrote
> > Naturally <g> I know nothing about the importance of heap especially

in this context or probbaly in any relevant context.

Show quoted text 8 lines
> > > How hard would it be? > > As non-shared heap is the default, this would be no problem ^^ > I am having difficulty interpreting '^^'. What is it meant to mean?

It's a Japanese emoticon for ":)". They do it vertically instead of horizontally and often I prefer those ;)
See also: http://en.m.wikipedia.org/wiki/Kaomoji

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131026/cca48264/attachment.html>

Sven Barth
to ListMember: OK, then. I'll take a look at that one. Thanks. I am having difficulty interpreting '^^'.…
"ListMember" wrote
On 2013-10-26 11:45, Sven Barth wrote: > > > If we could say that with enouh conjfidence, I'd gladly shift my focus

to fcl-passrc.

> > The main tests for what FPC supports and what not is for one compiling

(or in this context at least "parsing") the compiler's source, the RTL and the packages. Additionally there are the tests which should either succeed or dail to compile/run (and when a new feature is added at least one test is added). So in my opinion the ability to correctly parse compiler, RTL and packages sources plus correctly parsing all tests that should compile and failing all tests that should fail would be enough in my opinion.

> OK, then. I'll take a look at that one. Thanks.

And of course additional tests can be added and maybe we'll also need to mark some tests as "parses, but fails to compile" (e.g. to test linker errors, semantic errors or whatever).
Additionally one could try to make fcl-passrc a fragmentary parser so that it could be used for an IDE like Lazarus as well (code depublication) or for a Pascal script engine (I know there are already DWScript and PascalScript).

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131026/fe4f8317/attachment.html>

ListMember
to Sven Barth: to fcl-passrc. (or in this context at least "parsing") the compiler's source, the RTL and…
Sven Barth wrote 9 lines
And of course additional tests can be added and maybe we'll also need to mark some tests as "parses, but fails to compile" (e.g. to test linker errors, semantic errors or whatever). Additionally one could try to make fcl-passrc a fragmentary parser so that it could be used for an IDE like Lazarus as well (code depublication) or for a Pascal script engine (I know there are already DWScript and PascalScript).

One of my main hope is to come up with a fast enough code formatter with the options that I need.

Reason is, I am self-destructively (time and/or productivity-wise) pedantic about the way code is formatted. And, I sometimes find myself manually formatting stuff irrespective of how large the units are.

The other one is removal of 'with'. I find it one of the worst blocks imepeding refactoring. I have also been to known to spend days removing 'with's from units (e.g VirtualTrees.pas). And, even though I did write a special utility just to help me with that, I still managed to introduce subtle bugs that I cannot get rid of for the life of me.

To do it right, I need a parser thats smart enough to identify which variable/property/etc. belong to which object (in the case of derived objects, it needs to be able to go all the way back to TObject, if necessary) and rewrite the relevant portion of code.

I have started looking at fcl-passrc and it looks usable so far. But, I need to reformat it all :) And, then get it to work under D7.

Actually, I did get it to compile under D7 but that does not, of course, mean I have digested any of it yet.

If I may go back to the topic of 'compiler as dll' and use you as a sounding board for a moment:

What I had in mind was that the dll would have no access to disk/storage at all.

It would, instead, request and receive any unit it needs through streams --similarly, it would also output its binary through the same mechanism back to the owner application.

This would keep any changes from the user: I.e. the main application (as far as the user is concerned) would be the same compiler executable in text mode.

This would open up other uses, such as (with a suitably produced main application) remote development.

I think this would be especially useful for platforms that have limited storage; or conversely, the when the compiler's platform is stronger (more memory, faster cpu etc.) than the one the developer is using (laptop, tablet etc.)

Personally, I would love something mostly because I like (I am a lot more accustomed to) Windows better than other platforms for all sorts of things, and Lazarus appears to be more solid on Windows. Plus, I find using stuff like VNC or even RDP to be confusing to track where the cursonr/keyboard actioans will apply.

But, of course, if this were possible for Windows, it would also be possible for other platforms that Lazarus (or other IDEs) can be run.

Do you think this would be as useful as I am portraying it to be?

Or, if so, can it be done with reasonable effort --for someone better than I, I presume.

Martin
to ListMember
ListMember wrote
One of my main hope is to come up with a fast enough code formatter with the options that I need.

Have you looked at jedi? (Install package JCF).

It has plenty of options. BUt it fails parsing some newer code. But if you anyway are going to spent time, why not spending it o fixing jcf?

The other one is removal of 'with'.

Codetool has an option. (Refactor menu / pop.up). You can assign it to a keyboard shortcut.

ListMember
to Martin
Martin wrote 8 lines
On 26/10/2013 17:12, ListMember wrote: > > One of my main hope is to come up with a fast enough code formatter > with the options that I need. Have you looked at jedi? (Install package JCF). It has plenty of options. BUt it fails parsing some newer code. But if you anyway are going to spent time, why not spending it o fixing jcf?

I looked at it again some 3-4 years ago, I have issues with its internal/structural design: It uses indexed access in a very inelegant way that makes it also slow. I did try to refactor it to use trees/linklists internally, but I ran out of patience/stamina. As a result of all that, I won't touch JCF again. Sorry.

Show quoted text 6 lines
> > > The other one is removal of 'with'. Codetool has an option. (Refactor menu / pop.up). You can assign it to a keyboard shortcut.

This is interesting.

I didn't know that. Thank you for pointing it out?

Have you used it --i.e. is it any good?

Do you know whether it uses JCF or something else as the parser?

BTW, I've got Lazarus v1.0.12 here and I don't see anything in any popups that sound anything like 'remove with'; could you be a little more descriptive on the steps to wake up that beeast.

Sven Barth
to ListMember: One of my main hope is to come up with a fast enough code formatter with the options that…
"ListMember" wrote
I have started looking at fcl-passrc and it looks usable so far. But, I

need to reformat it all :) And, then get it to work under D7.

Please note that patches that change the formatting just for the sake of adjusting it to ones own taste are likely to be rejected. (just to avoid surprised reactions)

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131026/7759ea03/attachment.html>

Martin
to ListMember: I looked at it again some 3-4 years ago, I have issues with its internal/structural…
ListMember wrote 14 lines
On 2013-10-26 19:19, Martin wrote: >> >> >> The other one is removal of 'with'. > Codetool has an option. (Refactor menu / pop.up). You can assign it > to a keyboard shortcut. > This is interesting. I didn't know that. Thank you for pointing it out? Have you used it --i.e. is it any good?

Not used it... Not needed to use it yet

Do you know whether it uses JCF or something else as the parser?

Codetool has its own parser

BTW, I've got Lazarus v1.0.12 here and I don't see anything in any popups that sound anything like 'remove with'; could you be a little more descriptive on the steps to wake up that beeast.

Probably need to install package "Cody"

ListMember
to Sven Barth: need to reformat it all :) And, then get it to work under D7. Please note that patches…
Sven Barth wrote 10 lines
Am 26.10.2013 18:12 schrieb "ListMember" < <mailto:>>: > I have started looking at fcl-passrc and it looks usable so far. But, I need to reformat it all :) And, then get it to work under D7. Please note that patches that change the formatting just for the sake of adjusting it to ones own taste are likely to be rejected. (just to avoid surprised reactions)

I am ware of that.

But, formatting back to the style already used shouldn't be too hard: basically everything lowercase coupled with such economy of spaces that falls just a tad short of obfuscation ;)

[BTW, this isn't a comment on anyones formatting taste --just how it feels here.]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131026/ab970bb7/attachment-0001.html>

BTree Computing Services
to BTree Computing Services: In the Lazarus GUI, when components are placed on a form, vertical and horizontal design…

In the Lazarus GUI, when components are placed on a form, vertical and horizontal design guidelines are drawn to assist in aligning the component relative to other components. These lines are like 'laser lines' that shoot out from the edges. Does anyone know how that technique is done or the source code so that I can implement a similar technique in my app?

Thanks

Sven Barth
to BTree Computing Services: In the Lazarus GUI, when components are placed on a form, vertical and horizontal design…
BTree Computing Services wrote 6 lines
In the Lazarus GUI, when components are placed on a form, vertical and horizontal design guidelines are drawn to assist in aligning the component relative to other components. These lines are like 'laser lines' that shoot out from the edges. Does anyone know how that technique is done or the source code so that I can implement a similar technique in my app?

Please do not ask a new question as an answer to an existing thread. You might not receive any answers then, because people that could answer you, might ignore the thread.

So when asking a new question always write directly to (in this case) instead of using "answer to list".

Regards,
Sven

ListMember
to Juha Manninen: Yes, it is in Cody package mainly because the user interface is not as polished as it…
Juha Manninen wrote 6 lines
On Sat, Oct 26, 2013 at 8:13 PM, Martin wrote: > Probably need to install package "Cody" Yes, it is in Cody package mainly because the user interface is not as polished as it should be (according to Mattias). Cody has "advanced" features. I have used the "Explode a With block" feature and it works very well.

I have read a little more about codetools [
http://wiki.freepascal.org/Codetools ] and Cody [
http://wiki.freepascal.org/Cody ].

The combination of the two seems already able do a number of feats that not even professional/paid packages (that I know of in Delphi world) can.

I am wondering if it wouldn't be better idea (for me) to work on codetools rather than fcl-passrc?

Juha Manninen
to ListMember: I have read a little more about codetools [ http://wiki.freepascal.org/Codetools ] and…
ListMember wrote 9 lines
I have read a little more about codetools [ http://wiki.freepascal.org/Codetools ] and Cody [ http://wiki.freepascal.org/Cody ]. The combination of the two seems already able do a number of feats that not even professional/paid packages (that I know of in Delphi world) can. I am wondering if it wouldn't be better idea (for me) to work on codetools rather than fcl-passrc?

If you plan to modify code in-place then certainly yes. There was a plan to replace JCF parser with fcl-passrc but later I realized it would not work.
fcl-passrc is basically a one-way parser. Writing modified code back would loose both original formatting and comments. http://bugs.freepascal.org/view.php?id=19754

The downside of CodeTools is that it is not a full parser for the code. It stores in its parse tree definitions of types, variables, classes and functions but not the code itself. Yet, it provides primitives for help parsing the code.
For example Codetools is used for the Delphi converter. For replacement of functions it needs to parse the function parameters by itself.
The design of CodeTools makes it good for working on broken code while you are editing it. Code completion and browsing in editor work much better than in Delphi.

BTW, I did not notice that JCF parser is too slow. Its problem is that nobody is updating it for the latest pascal syntax. Both fcl-passrc and CodeTools are maintained better.

Juha

Mattias Gaertner
to BTree Computing Services: In the Lazarus GUI, when components are placed on a form, vertical and horizontal design…
Show quoted text 6 lines
In the Lazarus GUI, when components are placed on a form, vertical and horizontal design guidelines are drawn to assist in aligning the component relative to other components. These lines are like 'laser lines' that shoot out from the edges. Does anyone know how that technique is done or the source code so that I can implement a similar technique in my app?

designer/controlselection.pp

procedure TControlSelection.DrawGuideLines

Mattias