Sign in Join

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

Mailing lists / fpc-devel / 2010-06

crash with -gt -O2 in trunk

16 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

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

Martin

Ok, I should say first, I do not know if it is fpc, or lazarus. At the moment I guess fpc.

It only happens in trunk (15366, also seen with earlier trunk) / rel 2.4.0 seems to be not affected
It only happens in combination of -O2 and -gt together.

Compiled lazarus with: -gh -gt -g -gl -gw -godwarfsets -O2

According to the debugger (if it can be trusted on -O2) this is inside an end statement. It is also within the rtl. So the later makes me think it could be FPC

Since I am not familiar with this ode, I have no idea how to create a simple example that triggers the issue (for the same reason I do not know if it may be caused by something in Lazarus, passed to the RTL).

Observed on Windows Vista / stack is with laz rev 25916

Martin

Exception=Error reading ReplaceAllButton.Kind: Access violation Stack trace:
$0047ED1A line 1255 of ../objpas/classes/reader.inc $0047DF6B line 963 of ../objpas/classes/reader.inc $0047855B line 317 of ../objpas/classes/compon.inc $0047DCD2 line 927 of ../objpas/classes/reader.inc $0047DFF5 line 976 of ../objpas/classes/reader.inc $0047855B line 317 of ../objpas/classes/compon.inc $0047DCD2 line 927 of ../objpas/classes/reader.inc $0047DFF5 line 976 of ../objpas/classes/reader.inc $0047855B line 317 of ../objpas/classes/compon.inc $0047F74D line 1433 of ../objpas/classes/reader.inc $004C2970 line 3043 of lresources.pp
$004C27CC line 3063 of lresources.pp
$0041ED11 line 2749 of include/customform.inc
$0084AAC7 line 138 of findreplacedialog.pp
$0042EDB7 line 1477 of main.pp
$00402F33 line 103 of lazarus.pp

Reply by email

Jonas Maebe
to Martin
Martin wrote 6 lines
Ok, I should say first, I do not know if it is fpc, or lazarus. At the moment I guess fpc. It only happens in trunk (15366, also seen with earlier trunk) / rel 2.4.0 seems to be not affected It only happens in combination of -O2 and -gt together. Compiled lazarus with: -gh -gt -g -gl -gw -godwarfsets -O2

What about the RTL?

One common pitfall with -gt: it not only trashes local variables, but also "out" parameters. It happens from time to time that people expect "out" parameters to be unmodified if the callee doesn't modify it. Another problem is if you have something like do_assignment(const fromrec: trecord; out torec: trecord) and you call it like do_assignment(rec1,rec1). Since the torec parameter will be trashed on procedure entry and since the fromrec parameter may be passed by reference, the assigned value may become the trashed one instead of the original one.

There is at least one place in the rtl where this can happen in case it is compiled with -gt (the helper used when assigning a shortstring to another one), so in general I would recommend against compiling the rtl with -gt.

Jonas

Reply by email

Martin
to Jonas Maebe
Jonas Maebe wrote 12 lines
On 05 Jun 2010, at 18:09, Martin wrote: > Ok, I should say first, I do not know if it is fpc, or lazarus. At the moment I guess fpc. > > It only happens in trunk (15366, also seen with earlier trunk) / rel 2.4.0 seems to be not affected > It only happens in combination of -O2 and -gt together. > > Compiled lazarus with: -gh -gt -g -gl -gw -godwarfsets -O2 > What about the RTL?

* compiler was build using

..\trunk_build\make.exe clean distclean
..\trunk_build\make.exe rtl packages compiler LINKSMART=1 CREATESMART=1 OPTIMIZE=1 OPT="-O3 -Or -CpPENTIUMM -OpPENTIUMM" TARGET_EXAMPLES=NO FPC=c:\FPC\SVN\ppc386_2_4_0.exe ..\trunk_build\make.exe install INSTALL_PREFIX=c:\FPC\strunc\ COPYTREE=echo UPXPROG=echo

* RTL was build
..\trunk_build\make.exe rtl_clean packages_clean
..\trunk_build\make.exe rtl packages LINKSMART=1 CREATESMART=1 DEBUG=1 OPTIMIZE=0 OPT="-gl -gw -godwarfsets -O1" FPC=c:\FPC\strunc\bin\i386-win32\fpc.exe TARGET_EXAMPLES=NO ..\trunk_build\make.exe rtl_install packages_install INSTALL_PREFIX=c:\FPC\strunc\ COPYTREE=echo UPXPROG=echo FPC=c:\FPC\strunc\bin\i386-win32\fpc.exe

No -gt here.

Interesting too. The RTL was not modified between the builds => so the crash depended solely on the flags used to build lazarus/LCL

Show quoted text 9 lines
One common pitfall with -gt: it not only trashes local variables, but also "out" parameters. It happens from time to time that people expect "out" parameters to be unmodified if the callee doesn't modify it. Another problem is if you have something like do_assignment(const fromrec: trecord; out torec: trecord) and you call it like do_assignment(rec1,rec1). Since the torec parameter will be trashed on procedure entry and since the fromrec parameter may be passed by reference, the assigned value may become the trashed one instead of the original one. There is at least one place in the rtl where this can happen in case it is compiled with -gt (the helper used when assigning a shortstring to another one), so in general I would recommend against compiling the rtl with -gt. Jonas_______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Jonas Maebe
to Martin
Martin wrote
Interesting too. The RTL was not modified between the builds => so the crash depended solely on the flags used to build lazarus/LCL

I'm not aware of any potential problems caused by combining -O2 and -gt.

Jonas

Reply by email

Martin
to Jonas Maebe
Jonas Maebe wrote 8 lines
On 05 Jun 2010, at 19:13, Martin wrote: > Interesting too. The RTL was not modified between the builds => so the crash depended solely on the flags used to build lazarus/LCL > I'm not aware of any potential problems caused by combining -O2 and -gt.

Well the interesting thing is, it only happens under trunk, and in this combination.

so either -gt was improved to catch something it didn't catch before, or -O2 / -gt degraded to conflict with each other....

Ok, I caught it in the debugger:
Only problem is I don't know how reliable the values are, since -O2 isn't debugger friendly

#0 fpc_reraise at ..\inc\except.inc:305
#1 ?? at :0
#2 READPROPVALUE(0xd529588, 0x0, 0x0) at ..\objpas\classes\reader.inc:1379

      procedure TReader.ReadPropValue(Instance: TPersistent; PropInfo:

Pointer);
The location of the crash is shown as inside the "end;" of the procedure => but that may be the debugger not coping with the optimization level

Interstingly, at the time of crash, if looking at the stackframe, the debugger believes that the variable "Instance" is nil; now that would aco8unt for a crash.
The variable is not modified by the procedure (not as far as I can see) See comment below: it would appear it was none nil to start with. If it is indeed nil at the time of the crash => then where was it set to nil?

Same for PropInfo

#3 READPROPERTY(0xd529588, 0xdc97a60) at ..\objpas\classes\reader.inc:1235 looking at the frame of this procedure, both the variable passed in to [#2] are *not* nil

#4 READDATA(0xd529588, 0xdc97a60) at ..\objpas\classes\reader.inc:963 #5 READSTATE(0x0, 0x0) at ..\objpas\classes\compon.inc:317 #6 READSTATE(0xdc97a60, 0xd529588) at include\control.inc:3163 #7 READCOMPONENT(0xd529588, 0x0) at ..\objpas\classes\reader.inc:927 #8 READDATA(0xd529588, 0xdc976b0) at ..\objpas\classes\reader.inc:976 #9 READSTATE(0x0, 0x0) at ..\objpas\classes\compon.inc:317 #10 READSTATE(0xdc976b0, 0xd529588) at include\control.inc:3163 #11 READCOMPONENT(0xd529588, 0x0) at ..\objpas\classes\reader.inc:927 #12 READDATA(0xd529588, 0xdc88170) at ..\objpas\classes\reader.inc:976 #13 READSTATE(0x0, 0x0) at ..\objpas\classes\compon.inc:317 #14 READSTATE(0xdc88170, 0xd529588) at include\control.inc:3163 #15 READROOTCOMPONENT(0xd529588, 0xdc88170) at
..\objpas\classes\reader.inc:1433
#16 INITCOMPONENT(0xa3dfdb8, 0xd169bc) at lresources.pp:3043 #17 INITLAZRESOURCECOMPONENT(0xdc88170, 0xadaba8) at lresources.pp:3063 #18 ?? at :0
#19 $FORMS$_Ld121 at :0
#20 $FINDREPLACEDIALOG$_Ld3 at :0
#21 INITRESOURCECOMPONENT(0x0, 0x0) at lresources.pp:760 #22 CREATE(0xdc88170, 0x0, 0x0) at include\customform.inc:1854 #23 CREATE(0x0, 0xa3df740, 0xb96af8) at include\customform.inc:2749 #24 CREATE(0xb96af8, 0xa3df740, 0xd529588) at findreplacedialog.pp:138 #25 CREATEOFTENUSEDFORMS(0xa3df740) at main.pp:1477 #26 :103

----------------
within 2, I single stepped it
     tkEnumeration:
       begin
         Value := GetEnumValue(PropType, ReadIdent);
         if Value = -1 then
           raise EReadError.Create(SInvalidPropertyValue);
         SetOrdProp(Instance, PropInfo, Value);
       end;

it sets the property on the instance
property "Kind" on a TBitBtn

I single steped all through TBitBtn.SetKind without any sign of an exception there (yet I would expect something must have been changed there, as this is code that is affected by the compiler flags)

and reaches the procedure's "end" statement => and that's where the xecptio happens, or becomes note-able
(it goes into various fpc_AnsiStr_Decr_Ref and then ends up in fpc_ReRaise)

I have absolutely no idea.
I know it's possibl;e that it's a bug in the LCL, that is only revealed by the set of options, and only in trunk..

If you ask me about likelihoods, I would say it's a bug caused by the optimization (since 2.4.0 with the same settigns is fine.

As far as debugging goes from my site => that's the best I can do, withou any significant feedback from someone who knows more.

If someone can point out any revision in fpc trunk that had significant changes to -O2 or -gt => I can test them.
But please don't excpect me to test a dozend of them. (It takes ages to recompile, and my computer will be busy enough during this time to prevent me from doing anything.)

Martin

Reply by email

Jonas Maebe
to Martin
Martin wrote 15 lines
Ok, I caught it in the debugger: Only problem is I don't know how reliable the values are, since -O2 isn't debugger friendly #0 fpc_reraise at ..\inc\except.inc:305 #1 ?? at :0 #2 READPROPVALUE(0xd529588, 0x0, 0x0) at ..\objpas\classes\reader.inc:1379 procedure TReader.ReadPropValue(Instance: TPersistent; PropInfo: Pointer); The location of the crash is shown as inside the "end;" of the procedure => but that may be the debugger not coping with the optimization level Interstingly, at the time of crash, if looking at the stackframe, the debugger believes that the variable "Instance" is nil; now that would aco8unt for a crash. The variable is not modified by the procedure (not as far as I can see) See comment below: it would appear it was none nil to start with. If it is indeed nil at the time of the crash => then where was it set to nil? Same for PropInfo

The values of variables shown in the debugger cannot be relied upon when using -O2.

If someone can point out any revision in fpc trunk that had significant changes to -O2 or -gt => I can test them.

One thing that was added is the node level CSE optimiser. You can disable it with the -Oonocse command line option (put it in the command line after -O2). There are no changes to -gt that I remember.

Jonas

Reply by email

Martin
to Jonas Maebe
Jonas Maebe wrote 21 lines
On 05 Jun 2010, at 20:25, Martin wrote: > Ok, I caught it in the debugger: > Only problem is I don't know how reliable the values are, since -O2 isn't debugger friendly > > > #0 fpc_reraise at ..\inc\except.inc:305 > #1 ?? at :0 > #2 READPROPVALUE(0xd529588, 0x0, 0x0) at ..\objpas\classes\reader.inc:1379 > procedure TReader.ReadPropValue(Instance: TPersistent; PropInfo: Pointer); > The location of the crash is shown as inside the "end;" of the procedure => but that may be the debugger not coping with the optimization level > > Interstingly, at the time of crash, if looking at the stackframe, the debugger believes that the variable "Instance" is nil; now that would aco8unt for a crash. > The variable is not modified by the procedure (not as far as I can see) > See comment below: it would appear it was none nil to start with. If it is indeed nil at the time of the crash => then where was it set to nil? > > Same for PropInfo > The values of variables shown in the debugger cannot be relied upon when using -O2.

I know, but for those that did have a value, I can make a reasonable assumption that, if the value had properties like Fname => which pointed to the correct name-string, then that variable probably held the correct value...

As for them being nil => I don't thing that's the cause => that is simply what happens in the procedures "end" statement. As I said I single stepped through the method, and the called code => and there was no problem during that single stepping (unless it would have been an exception that gdb does not notice)

> If someone can point out any revision in fpc trunk that had significant changes to -O2 or -gt => I can test them. > One thing that was added is the node level CSE optimiser. You can disable it with the -Oonocse command line option (put it in the command line after -O2). There are no changes to -gt that I remember.

Unfortunately no luck.
-gh -g -gt -gl -gw -godwarfsets -CX -XX -Xs -O2 -Oonocse

I noted that if I compile with -Cr (range checks), then it fails earlier (ButtonPanel.Create) => but that is also shortly after bitbtn.kind (bitbtn.create) code. It also fails with a SigSegV, not with a range-check.

BitBtn.kind loads glyphs from resources... So there could be something there. Only it must be something that doesn't crash straight ahead. => like accessing random mem => or messng around with the stack a few frames above it's own stack (since I guess a sigsegv inside a procedures "end" means that the current stackframe got corrupted?)

Martin

Reply by email

Martin
to Martin
Martin wrote 14 lines
Unfortunately no luck. -gh -g -gt -gl -gw -godwarfsets -CX -XX -Xs -O2 -Oonocse I noted that if I compile with -Cr (range checks), then it fails earlier (ButtonPanel.Create) => but that is also shortly after bitbtn.kind (bitbtn.create) code. It also fails with a SigSegV, not with a range-check. BitBtn.kind loads glyphs from resources... So there could be something there. Only it must be something that doesn't crash straight ahead. => like accessing random mem => or messng around with the stack a few frames above it's own stack (since I guess a sigsegv inside a procedures "end" means that the current stackframe got corrupted?)

Just tested with 2.4.1 branch => no problems there

Martin

Reply by email

Martin
to Jonas Maebe: The values of variables shown in the debugger cannot be relied upon when using -O2. One…
Jonas Maebe wrote
One thing that was added is the node level CSE optimiser. You can disable it with the -Oonocse command line option (put it in the command line after -O2). There are no changes to -gt that I remember.

it wasn't cse.

It seems it is RegVar ( and -gt )

-gh -gt -g -gl -gw -godwarfsets -CX -XX -Xs -O2 -OpPENTIUMM -Oonoregvar
-gh -gt -g -gl -gw -godwarfsets -CX -XX -Xs -O2 -OpPENTIUMM

the first one, works fine, the 2nd causes the crash.

Martin

Reply by email

Martin
to Martin
Martin wrote 7 lines
It seems it is RegVar ( and -gt ) -gh -gt -g -gl -gw -godwarfsets -CX -XX -Xs -O2 -OpPENTIUMM -Oonoregvar -gh -gt -g -gl -gw -godwarfsets -CX -XX -Xs -O2 -OpPENTIUMM the first one, works fine, the 2nd causes the crash.

I have no idea if the following is relevant.
Compiling the same unit with/without -gt / both times with -O2 leads to some difference in the order registers are used.

In the example below this is probably not relevant => I wonder if in other cases it could be relevant.

.section .text.n_buttons_tcustombitbtn_$__realizekind .balign 16,0x90
.balign 16,0x90
.globl BUTTONS_TCUSTOMBITBTN_$__REALIZEKIND
BUTTONS_TCUSTOMBITBTN_$__REALIZEKIND:

* WITH -gt has the following extra lines (of course, since it does the random intialize)
.Ll205:
movb $85,-64(%ebp)
movb $85,-4(%ebp)
movl $0,%esi
movl $1431655765,-8(%ebp)
movl $1431655765,-12(%ebp)

* I noted neiter eax nor edx are in this code => so I wonder if they should be affected later on?

then they share the SAME code
movl $0,-56(%ebp)
leal -24(%ebp),%ecx
leal -48(%ebp),%edx
movl $1,%eax
call FPC_PUSHEXCEPTADDR
call FPC_SETJMP
pushl %eax
testl %eax,%eax
jne .Lj494

** and then:

**** with -gt
.Ll206:
# [185] if (Kind bkCustom) then
movl -60(%ebp),%eax
movl 852(%eax),%edx
testl %edx,%edx
je .Lj498

**** without -gt
.Ll194:
# [185] if (Kind bkCustom) then
movl -60(%ebp),%edx
movl 852(%edx),%eax
testl %eax,%eax
je .Lj498

==> eax and adx have just been swapped.

In this case the result should be the same, and since both cases are using both registers, the 2 registers should in both cases be avail for usage.

I wonder if in other cases, eax may drop in for edx (or vice versa) where it may cause a proble (data replaced?)

The question is, should -gt have caused this change?

Reply by email

Martin
to Martin: it wasn't cse. It seems it is RegVar ( and -gt ) -gh -gt -g -gl -gw -godwarfsets -CX…
Martin wrote 7 lines
On 05/06/2010 19:57, Jonas Maebe wrote: > > One thing that was added is the node level CSE optimiser. You can > disable it with the -Oonocse command line option (put it in the > command line after -O2). There are no changes to -gt that I remember. >

Comparing the assembler of the same file with and without -gt I noted soemthing else, I am not sure about

local vars are:
   GlyphValid, Handled: Boolean;
   CustomGlyph: TGraphic;
   BitmapHandle, MaskHandle: HBitmap;

As expected the begin of the method is equal, I only copied it for completeness

.section .text.n_buttons_tcustombitbtn_$__realizekind .balign 16,0x90
.balign 16,0x90
.globl BUTTONS_TCUSTOMBITBTN_$__REALIZEKIND
BUTTONS_TCUSTOMBITBTN_$__REALIZEKIND:
.Lc82:
# Temps allocated between ebp-76 and ebp-12
# path: .\include\
# file: bitbtn.inc
# indx: 2
.Ll204:
# [184] begin
pushl %ebp
.Lc84:
.Lc85:
movl %esp,%ebp
.Lc86:
subl $76,%esp
# Var $self located in register eax
# Var GlyphValid located in register al
# Var CustomGlyph located in register esi
movl %ebx,-76(%ebp)
movl %esi,-72(%ebp)
movl %edi,-68(%ebp)
# Var Handled located at ebp-4
# Var BitmapHandle located at ebp-8
# Var MaskHandle located at ebp-12
movl %eax,-60(%ebp)
# ============================= here starts the difference # here is the trashing of locals

.Ll205:
movb $85,-64(%ebp)
movb $85,-4(%ebp)
movl $0,%esi # <<<<<<<<<<<<<<<<<<<
movl $1431655765,-8(%ebp)
movl $1431655765,-12(%ebp)

The line I marked trashes " CustomGlyph: TGraphic"

Other objects are trashed with 1431655765 , but this one is trashed with $0 ? (that isn't really trash?)

Martin

Reply by email

Jonas Maebe
to Martin: I have no idea if the following is relevant. Compiling the same unit with/without -gt /…
Martin wrote 5 lines
In this case the result should be the same, and since both cases are using both registers, the 2 registers should in both cases be avail for usage. I wonder if in other cases, eax may drop in for edx (or vice versa) where it may cause a proble (data replaced?) The question is, should -gt have caused this change?

The register allocator uses a graph colouring algorithm. It can easily produce slightly different but equivalent register allocations when the graphs change (i.e., when more virtual registers are used, e.g. because of extra initialisation code). So yes, it is entirely expected that such changes occur with -gt.

Jonas

Reply by email

Martin
to Martin: Comparing the assembler of the same file with and without -gt I noted soemthing else, I…

I found another thing, I don't understand (or I suspect to be not ok) ( see also the 0 initialization by -gt as indicated in the other mail / below)

First method in buttons.pp

.section .text.n_buttons_getlcldefaultbtnglyph$tbitbtnkind$$tgraphic .balign 16,0x90
.balign 16,0x90
.globl BUTTONS_GETLCLDEFAULTBTNGLYPH$TBITBTNKIND$$TGRAPHIC BUTTONS_GETLCLDEFAULTBTNGLYPH$TBITBTNKIND$$TGRAPHIC: .Lc1:
# Temps allocated between esp+0 and esp+0
# Var Kind located in register eax
# Var $result located in register eax
# [buttons.pp]
# [452] begin
.Ll1:
movl $0,%edx
.Ll2:
# [453] Result := GetDefaultButtonIcon(BitBtnImages[Kind]); movl TC_BUTTONS_BITBTNIMAGES(,%eax,4),%eax
call BUTTONS_GETDEFAULTBUTTONICON$LONGINT$$TCUSTOMBITMAP .Ll3:
# [454] end;
ret

The code is identical between with/withou -gt => except for : movl $0,%edx

which is inserted by -gt
But edx isn't used at all (the call returns it's result in eax)?

So why trashing it, and why with 0?

Martin

Martin wrote 67 lines
On 06/06/2010 20:44, Martin wrote: > On 05/06/2010 19:57, Jonas Maebe wrote: >> >> One thing that was added is the node level CSE optimiser. You can >> disable it with the -Oonocse command line option (put it in the >> command line after -O2). There are no changes to -gt that I remember. >> > Comparing the assembler of the same file with and without -gt I noted soemthing else, I am not sure about local vars are: GlyphValid, Handled: Boolean; CustomGlyph: TGraphic; BitmapHandle, MaskHandle: HBitmap; As expected the begin of the method is equal, I only copied it for completeness .section .text.n_buttons_tcustombitbtn_$__realizekind .balign 16,0x90 .balign 16,0x90 .globl BUTTONS_TCUSTOMBITBTN_$__REALIZEKIND BUTTONS_TCUSTOMBITBTN_$__REALIZEKIND: .Lc82: # Temps allocated between ebp-76 and ebp-12 # path: .\include\ # file: bitbtn.inc # indx: 2 .Ll204: # [184] begin pushl %ebp .Lc84: .Lc85: movl %esp,%ebp .Lc86: subl $76,%esp # Var $self located in register eax # Var GlyphValid located in register al # Var CustomGlyph located in register esi movl %ebx,-76(%ebp) movl %esi,-72(%ebp) movl %edi,-68(%ebp) # Var Handled located at ebp-4 # Var BitmapHandle located at ebp-8 # Var MaskHandle located at ebp-12 movl %eax,-60(%ebp) # ============================= here starts the difference # here is the trashing of locals .Ll205: movb $85,-64(%ebp) movb $85,-4(%ebp) movl $0,%esi # <<<<<<<<<<<<<<<<<<< movl $1431655765,-8(%ebp) movl $1431655765,-12(%ebp) The line I marked trashes " CustomGlyph: TGraphic" Other objects are trashed with 1431655765 , but this one is trashed with $0 ? (that isn't really trash?) Martin _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Leonardo M. Ramé
to Martin

Hi, when I use html templates with tags that contains inner tags, the ReplaceTag event is fired only once, for the 1st order tag, but not for the inner tags. Example, a home page containing a header (a tag) and a body which contains another tag like, for example {+search_form+}. The search_form tag, also contains some {+tags+} to be replaced by the main program. Is there an "official" way to handle this use case?

Leonardo M. Ramé

http://leonardorame.blogspot.com

Reply by email

ABorka
to Leonardo M. Ramé
Leonardo M. Ramé wrote 12 lines
Hi, when I use html templates with tags that contains inner tags, the ReplaceTag event is fired only once, for the 1st order tag, but not for the inner tags. Example, a home page containing a header (a tag) and a body which contains another tag like, for example {+search_form+}. The search_form tag, also contains some {+tags+} to be replaced by the main program. Is there an "official" way to handle this use case? Leonardo M. Ramé http://leonardorame.blogspot.com

An example template attached would have helped, but guessing your problem...

If you use the "AllowTagParams := true;" for a template, then you cannot have recursive embedded tags. That is what the tag parameters can be used for instead.
For example:
{+search_form
[-formheader=<form blah blah>-]

[-formbody=<input type...>-]

[-formfooter=</form>-]
+}

Your program needs to replace the "search_form" tag by also processing the tag parameters.
To see some examples for template usage, try the demo programs under ...\lazarus\components\fpweb\demo\fptemplate\...

AB

Reply by email

Leonardo M. Ramé
to ABorka

Thanks I have forgotten the listings example.

Leonardo M. Ramé

http://leonardorame.blogspot.com

--- On Mon, 6/7/10, ABorka wrote:

Earlier message 40 lines
From: ABorka Subject: Re: [fpc-devel] fpWeb recursive tag replace To: "FPC developers' list" Date: Monday, June 7, 2010, 9:02 PM On 6/7/2010 16:40, Leonardo M. Ramé wrote: > Hi, when I use html templates with tags that contains inner tags, the > ReplaceTag event is fired only once, for the 1st order tag, but not for > the inner tags. > > Example, a home page containing a header (a tag) and a body which > contains another tag like, for example {+search_form+}. The search_form > tag, also contains some {+tags+} to be replaced by the main program. > > Is there an "official" way to handle this use case? > > Leonardo M. Ramé > http://leonardorame.blogspot.com An example template attached would have helped, but guessing your problem... If you use the "AllowTagParams := true;" for a template, then you cannot have recursive embedded tags. That is what the tag parameters can be used for instead. For example: {+search_form [-formheader=<form blah blah>-] [-formbody=<input type...>-] [-formfooter=</form>-] +} Your program needs to replace the "search_form" tag by also processing the tag parameters. To see some examples for template usage, try the demo programs under ...\lazarus\components\fpweb\demo\fptemplate\... AB

Reply by email